<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="cache-control" content="no-cache">
<title>Genivia - XML DOM API and domcpp</title>
<link href="genivia_tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="genivia_content.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="top">
 <div id="titlearea">
  <table height="72px" width="100%" cellspacing="0" cellpadding="0">
   <tbody>
    <tr>
     <td width="10%">&nbsp;</td>
     <td width="175px"><a href="https://www.genivia.com"><img alt="Genivia" src="GeniviaLogo2_trans_noslogan.png"/></a></td>
     <td class="tab_home"><a href="https://www.genivia.com">Home</a></td>
     <td class="tab_home"><a href="https://www.genivia.com/docs.html">Documentation</a></td>
     <td>
      <div style="float: right; font-size: 18px; font-weight: bold;">XML DOM API and domcpp</div>
      <br>
      <div style="float: right; font-size: 10px;">updated Wed Aug 11 2021 by Robert van Engelen</div>
     </td>
     <td width="10%">&nbsp;</td>
    </tr>
   </tbody>
  </table>
 </div>
<!-- Generated by Doxygen 1.8.11 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">XML DOM API and domcpp </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#intro">Introduction                                                            </a><ul><li class="level2"><a href="#intro-1">XML DOM and gSOAP                                                     </a></li>
<li class="level2"><a href="#intro-2">XML DOM versus XML data bindings                                      </a></li>
<li class="level2"><a href="#intro-3">Embedding serializable objects and data in DOM element nodes          </a><ul><li class="level3"><a href="#intro-3-1">Defining serializable types</a></li>
<li class="level3"><a href="#intro-3-2">Deserializing by XML element name or by type name</a></li>
<li class="level3"><a href="#intro-3-3">Using serializable types defined in C++ namespaces</a></li>
</ul>
</li>
</ul>
</li>
<li class="level1"><a href="#domcpp">The domcpp command-line tool                                           </a><ul><li class="level2"><a href="#domcpp-1">Building and installing domcpp                                       </a></li>
<li class="level2"><a href="#domcpp-2">Command-line options                                                 </a></li>
<li class="level2"><a href="#domcpp-3">XPath syntax support for domcpp                                      </a></li>
<li class="level2"><a href="#domcpp-4">XPath by example                                                     </a></li>
</ul>
</li>
<li class="level1"><a href="#ns">Understanding XML namespaces                                               </a></li>
<li class="level1"><a href="#cpp">C++ XML DOM API                                                           </a><ul><li class="level2"><a href="#cpp-files">List of C++ files                                                   </a></li>
<li class="level2"><a href="#cpp-api">C++ DOM API functions                                                 </a><ul><li class="level3"><a href="#cpp-api1">Creating a DOM root element node</a></li>
<li class="level3"><a href="#cpp-api2">Assigning child nodes and values to a DOM node</a></li>
<li class="level3"><a href="#cpp-api3">Matching and retrieving DOM node values and properties</a></li>
<li class="level3"><a href="#cpp-api4">Traversing a DOM node graph</a></li>
<li class="level3"><a href="#cpp-api5">Searching a DOM node graph</a></li>
<li class="level3"><a href="#cpp-api6">XML DOM parsing and writing from/to streams</a></li>
</ul>
</li>
</ul>
</li>
<li class="level1"><a href="#c">C XML DOM API                                                               </a><ul><li class="level2"><a href="#c-files">List of C files                                                       </a></li>
<li class="level2"><a href="#c-api">C DOM API functions                                                     </a><ul><li class="level3"><a href="#c-api1">Creating a DOM root element node</a></li>
<li class="level3"><a href="#c-api2">Assigning child nodes and values to a DOM node</a></li>
<li class="level3"><a href="#c-api3">Matching and retrieving DOM node values and properties</a></li>
<li class="level3"><a href="#c-api4">Traversing a DOM node graph</a></li>
<li class="level3"><a href="#c-api5">Searching a DOM node graph</a></li>
<li class="level3"><a href="#c-api6">XML DOM parsing and writing from/to streams</a></li>
</ul>
</li>
</ul>
</li>
<li class="level1"><a href="#opt">XML DOM parsing and display options                                       </a></li>
<li class="level1"><a href="#dom">Using DOM together with serializeble types in a gSOAP header file         </a></li>
<li class="level1"><a href="#example">Example                                                               </a></li>
<li class="level1"><a href="#misc">Miscellaneous                                                            </a><ul><li class="level2"><a href="#fp">Floating point format                                                      </a></li>
</ul>
</li>
<li class="level1"><a href="#copyright">Copyright                                                           </a></li>
</ul>
</div>
<div class="textblock"><h1><a class="anchor" id="intro"></a>
Introduction                                                            </h1>
<p>XML data bindings provide a powerful mechanism to parse, validate, manipulate, and write XML data with ease as if we are working with native C and C++ data. Occasionally we will need to work with raw XML data. Raw XML can be parsed with a DOM parser and stored in a DOM node graph. The DOM (Document Object Model) node graph (actually a node tree) can be inspected to retrieve text and other values. We can iteratively and recursively traverse the XML tree via its DOM node graph at increasingly deeper levels to inspect and retrieve values of XML elements and attributes. We can also use XPath queries to locate data deep in the DOM node hierarchy to retrieve specific values.</p>
<p>The gSOAP XML DOM API is compact in size but offers a wealth of operations to construct, inspect, traverse, and search data in DOM node graphs. The DOM API offers powerful constructors to construct a DOM node graph for XML with <b>smart XML namespace handling</b> to simplify coding. The DOM API also offers a hybrid <b>DOM + data binding approach</b> that allows you to embed serializable C/C++ data types including user-defined structs and classes. You can also search and retrieve values from XML and XML with namespaces using the DOM API's smart XML namespace handling.</p>
<p>We also offer a new code generation tool, <b>domcpp</b>, that greatly simplifies writing DOM API code by generating DOM construction code, DOM inspection code, and XPath code to query a DOM. The generated code uses the DOM API transparently in C and C++ (C++ by default and pure C as an option). So it is easy to get familiar with the DOM API by using the domcpp tool. In the first part of this introduction we show how to effectively use the domcpp tool to get started. The <b>domcpp</b> application is located in the gSOAP distribution package under <code>gsoap/samples/dom</code> and is built with: </p><pre class="fragment">cd gsoap/samples/dom
make domcpp
</pre><p>This document describes <b>domcpp</b> and the C and C++/C++11 DOM APIs of gSOAP, see table of contents.</p>
<h2><a class="anchor" id="intro-1"></a>
XML DOM and gSOAP                                                     </h2>
<p>To help you quickly develop C/C++ code to construct, inspect, and search DOM node graphs using the XML DOM API, we offer a new code generator <b>domcpp</b> with the gSOAP package (version 2.8.28 and up). You can find the domcpp tool with the DOM examples in <code>gsoap/samples/dom</code>.</p>
<p>The domcpp command-line tool auto-generates C or C++ code from an XML fragment. The generated code creates a DOM node graph for this fragment, which can be further tweaked as necessary. Let's demonstrate this with an example <code>menu.xml</code> XML file, where we show each command executed in a command shell followed by the results displayed in the terminal: </p><pre class="fragment">cat menu.xml
</pre><div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;menu id=&quot;file&quot; value=&quot;File&quot;&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;  &lt;popup&gt;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;    &lt;menuitem value=&quot;New&quot; onclick=&quot;CreateNewDoc()&quot; /&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;    &lt;menuitem value=&quot;Open&quot; onclick=&quot;OpenDoc()&quot; /&gt;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;    &lt;menuitem value=&quot;Close&quot; onclick=&quot;CloseDoc()&quot; /&gt;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  &lt;/popup&gt;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;&lt;/menu&gt;</div></div><!-- fragment --> </div> <pre class="fragment">domcpp menu.xml
</pre><div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line">{</div><div class="line">  <span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line">  ctx-&gt;double_format = <span class="stringliteral">&quot;%lG&quot;</span>;</div><div class="line"></div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;menu&quot;</span>);</div><div class="line">  dom.att(<span class="stringliteral">&quot;id&quot;</span>) = <span class="stringliteral">&quot;file&quot;</span>;</div><div class="line">  dom.att(<span class="stringliteral">&quot;value&quot;</span>) = <span class="stringliteral">&quot;File&quot;</span>;</div><div class="line">  dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][1].att(<span class="stringliteral">&quot;value&quot;</span>) = <span class="stringliteral">&quot;New&quot;</span>;</div><div class="line">  dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][1].att(<span class="stringliteral">&quot;onclick&quot;</span>) = <span class="stringliteral">&quot;CreateNewDoc()&quot;</span>;</div><div class="line">  dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][2].att(<span class="stringliteral">&quot;value&quot;</span>) = <span class="stringliteral">&quot;Open&quot;</span>;</div><div class="line">  dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][2].att(<span class="stringliteral">&quot;onclick&quot;</span>) = <span class="stringliteral">&quot;OpenDoc()&quot;</span>;</div><div class="line">  dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][3].att(<span class="stringliteral">&quot;value&quot;</span>) = <span class="stringliteral">&quot;Close&quot;</span>;</div><div class="line">  dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][3].att(<span class="stringliteral">&quot;onclick&quot;</span>) = <span class="stringliteral">&quot;CloseDoc()&quot;</span>;</div><div class="line">  std::cout &lt;&lt; dom &lt;&lt; std::endl;</div><div class="line"></div><div class="line">  soap_destroy(ctx); <span class="comment">// delete objects</span></div><div class="line">  soap_end(ctx);     <span class="comment">// delete DOM data</span></div><div class="line">  soap_free(ctx);    <span class="comment">// free context</span></div><div class="line">}</div></div><!-- fragment --><p>When comparing this C++ source code to C source code generated by domcpp, you will notice that the generated source code for pure C is similar to the C++ source code, but uses the C DOM API functions directly instead of C++ methods: </p><pre class="fragment">domcpp -c menu.xml
</pre><div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line">{</div><div class="line">  <span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line">  ctx-&gt;double_format = <span class="stringliteral">&quot;%lG&quot;</span>;</div><div class="line"></div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;menu&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, NULL, <span class="stringliteral">&quot;id&quot;</span>), <span class="stringliteral">&quot;file&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;File&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(<a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>), NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 1), NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;New&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(<a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>), NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 1), NULL, <span class="stringliteral">&quot;onclick&quot;</span>), <span class="stringliteral">&quot;CreateNewDoc()&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(<a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>), NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 2), NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;Open&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(<a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>), NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 2), NULL, <span class="stringliteral">&quot;onclick&quot;</span>), <span class="stringliteral">&quot;OpenDoc()&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(<a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>), NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 3), NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;Close&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(<a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>), NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 3), NULL, <span class="stringliteral">&quot;onclick&quot;</span>), <span class="stringliteral">&quot;CloseDoc()&quot;</span>);</div><div class="line">  <a class="code" href="dom_8cpp.html#afd8f56d71b8afa28ea394033b440ca2f">soap_write_xsd__anyType</a>(ctx, dom), putchar(<span class="charliteral">&#39;\n&#39;</span>);</div><div class="line"></div><div class="line">  soap_end(ctx);  <span class="comment">/* delete DOM data */</span></div><div class="line">  soap_free(ctx); <span class="comment">/* free context */</span></div><div class="line">}</div></div><!-- fragment --><p>You can use domcpp option <code>-M</code> to narrow the generated code down to the essentials, without the initialization and cleanup parts in the generated source code. This makes the generated code suitable for direct inclusion in your codebase.</p>
<p>You can use domcpp option <code>-e</code> to add explanatory comments to the generated code, which explains what the code does to help you understand the DOM API by including XPath path locations and other details.</p>
<p>In fact, the C++ DOM API is designed around the concept of XPath's path location to construct a node graph by aligning the C++ <code>[]</code> overloaded operator to XPath's path steps and position predicates. You can use domcpp option <code>-e</code> to reveal the XPath for each assignment statement. For example:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;menu&quot;</span>);</div><div class="line"><span class="comment">// /menu/@id = file</span></div><div class="line">dom.<a class="code" href="structsoap__dom__element.html#a98b830864204c90f40162875ab6574cc">att</a>(<span class="stringliteral">&quot;id&quot;</span>) = <span class="stringliteral">&quot;file&quot;</span>;</div><div class="line"><span class="comment">// /menu/@value = File</span></div><div class="line">dom.<a class="code" href="structsoap__dom__element.html#a98b830864204c90f40162875ab6574cc">att</a>(<span class="stringliteral">&quot;value&quot;</span>) = <span class="stringliteral">&quot;File&quot;</span>;</div><div class="line"><span class="comment">// /menu/popup/menuitem[1]/@value = New</span></div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][1].<a class="code" href="structsoap__dom__element.html#a98b830864204c90f40162875ab6574cc">att</a>(<span class="stringliteral">&quot;value&quot;</span>) = <span class="stringliteral">&quot;New&quot;</span></div></div><!-- fragment --><p>Generating code to populate a DOM node graph is one option. Another option is to generate code to inspect a DOM node graph. Use domcpp option <code>-i</code> to generate code to inspect the DOM node graph of XML parsed from input, given that the XML file provided with option <code>-i</code> serves as a generic template: </p><pre class="fragment">domcpp -i menu.xml
</pre><div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line">{</div><div class="line">  <span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line">  ctx-&gt;double_format = <span class="stringliteral">&quot;%lG&quot;</span>;</div><div class="line"></div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx);</div><div class="line">  std::cin &gt;&gt; dom;</div><div class="line">  <span class="keywordflow">if</span> (dom.soap-&gt;error)</div><div class="line">    exit(EXIT_FAILURE); <span class="comment">// error parsing XML</span></div><div class="line">  <a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att;</div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt;</div><div class="line"><span class="preprocessor">  #define USE_ATT(path, text) std::cout &lt;&lt; path &lt;&lt; &quot; = &quot; &lt;&lt; text &lt;&lt; std::endl</span></div><div class="line"><span class="preprocessor">  #define USE_ELT(path, text) std::cout &lt;&lt; path &lt;&lt; &quot; = &quot; &lt;&lt; text &lt;&lt; std::endl</span></div><div class="line">  <span class="keywordflow">if</span> ((att = dom.att_get(<span class="stringliteral">&quot;id&quot;</span>)))</div><div class="line">    USE_ATT(<span class="stringliteral">&quot;/menu/@id&quot;</span>, att-&gt;<a class="code" href="structsoap__dom__attribute.html#ab01efb4235deeeb4e92597f72b2e368c">get_text</a>());</div><div class="line">  <span class="keywordflow">if</span> ((att = dom.att_get(<span class="stringliteral">&quot;value&quot;</span>)))</div><div class="line">    USE_ATT(<span class="stringliteral">&quot;/menu/@value&quot;</span>, att-&gt;<a class="code" href="structsoap__dom__attribute.html#ab01efb4235deeeb4e92597f72b2e368c">get_text</a>());</div><div class="line">  <span class="keywordflow">if</span> ((elt = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;popup&quot;</span>)))</div><div class="line">  {</div><div class="line">    <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; dom_popup = *elt;</div><div class="line">    <span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it = dom_popup.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;menuitem&quot;</span>); it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>())</div><div class="line">    {</div><div class="line">      <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; dom_popup_menuitem = *it;</div><div class="line">      <span class="keywordflow">if</span> ((att = dom_popup_menuitem.<a class="code" href="structsoap__dom__element.html#a0db7e0873c5ae41e66d11c0ff54c2b09">att_get</a>(<span class="stringliteral">&quot;value&quot;</span>)))</div><div class="line">        USE_ATT(<span class="stringliteral">&quot;/menu/popup/menuitem/@value&quot;</span>, att-&gt;<a class="code" href="structsoap__dom__attribute.html#ab01efb4235deeeb4e92597f72b2e368c">get_text</a>());</div><div class="line">      <span class="keywordflow">if</span> ((att = dom_popup_menuitem.<a class="code" href="structsoap__dom__element.html#a0db7e0873c5ae41e66d11c0ff54c2b09">att_get</a>(<span class="stringliteral">&quot;onclick&quot;</span>)))</div><div class="line">        USE_ATT(<span class="stringliteral">&quot;/menu/popup/menuitem/@onclick&quot;</span>, att-&gt;<a class="code" href="structsoap__dom__attribute.html#ab01efb4235deeeb4e92597f72b2e368c">get_text</a>());</div><div class="line">    }</div><div class="line">  }</div><div class="line">  std::cout &lt;&lt; dom &lt;&lt; std::endl;</div><div class="line"></div><div class="line">  soap_destroy(ctx); <span class="comment">// delete objects</span></div><div class="line">  soap_end(ctx);     <span class="comment">// delete DOM data</span></div><div class="line">  soap_free(ctx);    <span class="comment">// free context</span></div><div class="line">}</div></div><!-- fragment --><p>You can also use domcpp option <code>-p</code> to generate efficient XPath query code to query and retrieve specific XML values.</p>
<p>For example, let's write an XPath query to display the authors of books in a store. We will read the XML data from <code>std:cin</code> and filter the authors with the query <code>/store/book/@author</code> to collect them in a DOM node graph <code>y</code> containing the query results with domcpp option <code>-y</code>. We generate the code from the command line with domcpp as follows: </p><pre class="fragment">domcpp -M -p'/store/book/@author' -y
</pre><div class="fragment"><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx);</div><div class="line">std::cin &gt;&gt; dom;</div><div class="line"><span class="comment">// XPath: /store/book/@author</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att;</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt;</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> y(ctx, <span class="stringliteral">&quot;results&quot;</span>);</div><div class="line"><span class="preprocessor">#define QUERY_YIELD_ATT(v) y.add(xsd__anyType(ctx, &quot;result&quot;).add(v));</span></div><div class="line"><span class="preprocessor">#define QUERY_YIELD_ELT(v) y.add(xsd__anyType(ctx, &quot;result&quot;).add(v));</span></div><div class="line"><span class="keywordflow">if</span> (dom.match(<span class="stringliteral">&quot;store&quot;</span>))</div><div class="line">{</div><div class="line">  <span class="keywordtype">size_t</span> pos = 1;</div><div class="line">  <span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;book&quot;</span>); it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>(), ++pos)</div><div class="line">  {</div><div class="line">    <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; v = *it;</div><div class="line">    <span class="keywordflow">if</span> ((att = v.<a class="code" href="structsoap__dom__element.html#a0db7e0873c5ae41e66d11c0ff54c2b09">att_get</a>(<span class="stringliteral">&quot;author&quot;</span>)))</div><div class="line">    {</div><div class="line">      <a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a>&amp; v = *att;</div><div class="line">      QUERY_YIELD_ATT(v);</div><div class="line">    }</div><div class="line">  }</div><div class="line">}</div></div><!-- fragment --><p>Let's apply this query to the <code>store.xml</code> file that you can find in section <a href="#domcpp-4">XPath by example</a>: </p><pre class="fragment">./query &lt; store.xml
</pre><div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;results&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;  &lt;result author=&quot;Nigel Rees&quot;/&gt;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;  &lt;result author=&quot;Evelyn Waugh&quot;/&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;  &lt;result author=&quot;Herman Melville&quot;/&gt;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;  &lt;result author=&quot;J. R. R. Tolkien&quot;/&gt;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;&lt;/results&gt;</div></div><!-- fragment --> </div><p>You can compile this example yourself with: </p><pre class="fragment">domcpp -o query.cpp -m -p'/store/book/@author' -y
soapcpp2 -CSL import/dom.h
c++ -o query query.cpp soapC.cpp dom.cpp stdsoap2.cpp
</pre><p>You can also embed C/C++ code in XPath queries to filter and select values from XML at runtime.</p>
<p>The domcpp code generator aims to produce clean, high-quality and readable C and C++ code. You can also embed C/C++ code in XPath queries to filter and select values from XML data at runtime.</p>
<p>We will present domcpp in more detail in the next section. The remainder of this document explains how you can use the DOM C and C++ APIs to create XML data, access XML data, send/recv data via REST, and to read/write XML data to files, streams, and string buffers.</p>
<h2><a class="anchor" id="intro-2"></a>
XML DOM versus XML data bindings                                      </h2>
<p>XML data bindings greatly simplify the development of XML applications. Compared to DOM manipulation and search by DOM tree traversal, all that is needed are declarations of the C/C++ data types that need to be serializable in XML by using the soapcpp2 tool the generate the data binding implementation. Furthermore, XML parsing is much faster with XML data bindings. XML is efficiently pulled and converted by the C/C++ deserializers.</p>
<p>For more details, see <a href="http://www.genivia.com/doc/databinding/html">XML Data Bindings</a>.</p>
<p>On the other hand, you can use the XML DOM API to develop REST operations for SOAP and XML messaging by composing and decomposing the XML manually. For example in C++:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="keyword">struct </span>Namespace <a class="code" href="dom2calc_8cpp.html#aabfac0a3b8d38498bc5e1e3bc465ead6">namespaces</a>[] = {</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENV&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span>},</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENC&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span>},</div><div class="line">  {<span class="stringliteral">&quot;xsi&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>},</div><div class="line">  {<span class="stringliteral">&quot;xsd&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema&quot;</span>},</div><div class="line">  {<span class="stringliteral">&quot;t&quot;</span>,        <span class="stringliteral">&quot;http://tempuri.org/t.xsd&quot;</span>},</div><div class="line">  {NULL,       NULL}</div><div class="line">};</div><div class="line"><span class="keywordtype">int</span> <a class="code" href="dom2calc_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main</a>()</div><div class="line">{</div><div class="line">  soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> *endpoint = <span class="stringliteral">&quot;http://www.cs.fsu.edu/~engelen/gmtlitserver.cgi&quot;</span>;</div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> req(ctx, <span class="stringliteral">&quot;SOAP-ENV:Envelope&quot;</span>); <span class="comment">// DOM with SOAP envelope</span></div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> res(ctx);                      <span class="comment">// DOM for SOAP response</span></div><div class="line">  req[<span class="stringliteral">&quot;SOAP-ENV:Body&quot;</span>][<span class="stringliteral">&quot;t:gmt&quot;</span>] = <span class="stringliteral">&quot;&quot;</span>;         <span class="comment">// SOAP Body with &lt;t:gmt&gt;</span></div><div class="line">  <a class="code" href="dom_8cpp.html#ac69b3f6b7f7ee9f695050632b9c26fdc">soap_dom_call</a>(ctx,                          <span class="comment">// make a call (POST)</span></div><div class="line">      endpoint,                               <span class="comment">// the service endpoint URL</span></div><div class="line">      NULL,                                   <span class="comment">// no SOAPAction header</span></div><div class="line">      req,                                    <span class="comment">// request t:gmt</span></div><div class="line">      res);                                   <span class="comment">// response, if OK</span></div><div class="line">  <span class="keywordflow">if</span> (ctx-&gt;error) ...                         <span class="comment">// handle IO error</span></div><div class="line">  <a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> i = res.find(<span class="stringliteral">&quot;param-1&quot;</span>);</div><div class="line">  <span class="keywordflow">if</span> (i != res.end())                         <span class="comment">// if found, display time</span></div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Current time = &quot;</span> &lt;&lt; i-&gt;get_text() &lt;&lt; endl;</div><div class="line">}</div></div><!-- fragment --><p>The <code>SOAP_DOM_TREE</code> context flag used here disables the deserialization of embedded objects and data, which will be discussed in the next section.</p>
<p>Other REST methods can be used to manage the state of resources via URL references, allowing for the storage of data (HTTP PUT), retrieval of data (HTTP GET), and removal of data (HTTP DELETE) from a resource. The <code>soap_dom_call</code> function takes NULL as the service input request and service output response parameters to facilitate PUT (NULL for response), GET (NULL for request), and DELETE (both request and response are NULL).</p>
<p>However, XML data bindings greatly simplify the development of XML applications such as client and server runtimes for XML messaging and message validation. Compared to DOM manipulation and search by DOM tree traversal, all that is needed are declarations of server operations as C functions and the C/C++ data types passed to these functions.</p>
<p>For example, with XML data bindings it only takes one line to declare the SOAP/XML service operation:</p>
<div class="fragment"><div class="line">t__gmt(time_t*);</div></div><!-- fragment --><p>The soapcpp2 tool generates the data binding implementation such that <code>t__gmt</code> can be invoked as a function in a client-side C or C++ runtime:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;t.nsmap&quot;</span></div><div class="line"><span class="keywordtype">int</span> <a class="code" href="dom2calc_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main</a> ()</div><div class="line">{</div><div class="line">  soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT);</div><div class="line">  time_t t;</div><div class="line">  soap_call_t__gmt(ctx, endpoint, NULL, &amp;t);</div><div class="line">  <span class="keywordflow">if</span> (ctx-&gt;error == SOAP_OK)</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Current time = &quot;</span> &lt;&lt; ctime(t) &lt;&lt; endl;</div><div class="line">}</div></div><!-- fragment --><p>The gSOAP DOM API offers a hybrid <b>DOM + data binding approach</b> that allows you to use DOM nodes a members of serializable structs and classes (these DOM parts are auto-generated by wsdl2h with option <code>-d</code>). This hybrid approach also allows you to embed serializable C/C++ data into a DOM node graph. This way, you get the best of both XML DOM and XML data bindings.</p>
<h2><a class="anchor" id="intro-3"></a>
Embedding serializable objects and data in DOM element nodes          </h2>
<p>C and C++ objects and types can be serialized and deserialized when embedded in a DOM node.</p>
<h3><a class="anchor" id="intro-3-1"></a>
Defining serializable types</h3>
<p>To embed serializable data types we first define these types in a header file for soapcpp2 to generate the data binding code. We also import <code><a class="el" href="dom_8h.html">dom.h</a></code> from <code>gsoap/import</code> to use the DOM API:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;<a class="code" href="dom_8h.html">import/dom.h</a>&quot;</span></div><div class="line"><span class="comment">//gsoap t schema namespace: urn:demotime</span></div><div class="line"><span class="keyword">typedef</span> time_t _t__time;</div></div><!-- fragment --><p>This is a very small example to illustrate the concept. You can add declarations of data types to serialize. If XML namespaces are used in the XML document, then follow the naming conventions outlined in <a href="http://www.genivia.com/doc/databinding/html/index.html#toxsd2">XML Data Bindings: Colon notation versus name prefixing</a>.</p>
<p>Importing <code><a class="el" href="dom_8h.html">dom.h</a></code> is automated with wsdl2h option <code>-d</code> when running wsdl2h on WSDL and XSD files to produce a header file with the data binding interface for soapcpp2. Here, we assume you are starting with a header file for soapcpp2 with the declarations of C/C++ types to serialize.</p>
<p>We use soapcpp2 to generate the data binding implementation code together with the DOM API in <code>soapStub.h</code>, <code>soapH.h</code>, <code>soapC.cpp</code> and a namespace table file <code>t.nsmap</code> and <code>t.xsd</code> schema that declares a <code>time</code> type (at line 11) and also an element (at line 15) because by convention the <code>_t__time</code> type name is prefixed with a <code>_</code>:</p>
<div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;schema targetNamespace=&quot;urn:demotime&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;    xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;    xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;    xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;    xmlns:t=&quot;urn:demotime&quot;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;    xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;    elementFormDefault=&quot;unqualified&quot;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;    attributeFormDefault=&quot;unqualified&quot;&gt;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;  &lt;import namespace=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;/&gt;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;  &lt;simpleType name=&quot;time&quot;&gt;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;    &lt;restriction base=&quot;xsd:dateTime&quot;&gt;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;    &lt;/restriction&gt;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;  &lt;/simpleType&gt;</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;  &lt;element name=&quot;time&quot; type=&quot;xsd:dateTime&quot;/&gt;</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;&lt;/schema&gt;</div></div><!-- fragment --> </div><p>For details on declaring C/C++ types for XML data bindings and serialization, see <a href="http://www.genivia.com/doc/databinding/html/index.html#toxsd9-7">XML Data Bindings: Defining document root elements</a>.</p>
<p>You can use these serializable types declared in the header file as embedded serializable objects and data in DOM element nodes. The <code>SOAP_DOM_NODE</code> context flag should be set to enable this feature.</p>
<p>In the following example we use <code>_t__time</code> to construct a DOM for an XML root element <code>&lt;t:time&gt;</code> that contains an embedded serializable <code>time_t</code> value:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;t.nsmap&quot;</span></div><div class="line"><span class="keywordtype">int</span> <a class="code" href="dom2calc_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main</a>()</div><div class="line">{</div><div class="line">  soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_NODE);</div><div class="line">  time_t t = time(0);</div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, NULL, <span class="stringliteral">&quot;t:time&quot;</span>, &amp;t, SOAP_TYPE__t__time);</div><div class="line">  cout &lt;&lt; dom &lt;&lt; endl;     <span class="comment">// write XML &lt;t:time&gt;...&lt;/t:time&gt;</span></div><div class="line">  <span class="keywordflow">if</span> (dom.soap-&gt;error)</div><div class="line">    ... <span class="comment">// handle IO error</span></div><div class="line">}</div></div><!-- fragment --><p>and to parse and deserialize a <code>&lt;t:time&gt;</code> into a <code>time_t</code> value:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;t.nsmap&quot;</span></div><div class="line"><span class="keywordtype">int</span> <a class="code" href="dom2calc_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main</a>()</div><div class="line">{</div><div class="line">  soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_NODE);</div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx);</div><div class="line">  cin &gt;&gt; dom;              <span class="comment">// parse XML &lt;t:time&gt;...&lt;t:time&gt;</span></div><div class="line">  <span class="keywordflow">if</span> (dom.soap-&gt;error)</div><div class="line">    ... <span class="comment">// handle IO error</span></div><div class="line">  <span class="keyword">const</span> time_t *t = <span class="keyword">static_cast&lt;</span><span class="keyword">const </span>time_t*<span class="keyword">&gt;</span>(dom.get_node(SOAP_TYPE__t__time));</div><div class="line">  <span class="keywordflow">if</span> (t)</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Time = &quot;</span> &lt;&lt; ctime(t) &lt;&lt; endl;</div><div class="line">}</div></div><!-- fragment --><h3><a class="anchor" id="intro-3-2"></a>
Deserializing by XML element name or by type name</h3>
<p>With the <code>SOAP_DOM_NODE</code> flag set, there are two ways the C/C++ types are deserialized into DOM elements: by element tag name matching or by xsi:type matching:</p>
<ol type="1">
<li>If an xsi:type attribute is present (which requires preparations on the sending side), then its value is matched against the names of the C/C++ types to select a deserializer to parse and deserialize the data into a DOM element node as embedded objects/data. If no xsi:type attribute is present or if no serializer is found, then:</li>
<li>The element tag is matched against the names of serializable C/C++ types to select a deserializer to deserialize the data into a DOM element node as embedded objects/data. If no deserializer is found then the XML element is parsed and stored as a DOM element node.</li>
</ol>
<p>While <code>SOAP_DOM_NODE</code> instructs the DOM parser to deserialize the values of C/C++ types that match element tags, the opposite, <code>SOAP_DOM_TREE</code> prevents deserialization, even when an <code>id</code> attribute is present in the XML payload. The default is to deserialze only when an <code>id</code> attribute is present in the XML payload. This is to ensure that the SOAP encoding protocol deos not break when id-ref attibutes are used for multireferenced objects.</p>
<h3><a class="anchor" id="intro-3-3"></a>
Using serializable types defined in C++ namespaces</h3>
<p>The C++ DOM API is unaware of serializable C++ types defined in C++ namespaces. The DOM API only "sees" globally defined types to serialize and deserialize. This can lead to errors when trying to serialize or deserialize an object in a DOM node that is defined in a C++ namespace.</p>
<p>When a client or service application is built with C++ namespaces, either using soapcpp2 with option <code>-q</code> or with a <code>namespace</code> declaration in the .h interface header file for soapcpp2, then you should take care to compile the source code of the DOM API to check for types defined in an external namespace by compiling <code><a class="el" href="dom_8cpp.html">dom.cpp</a></code> using <code>-DSOAP_DOM_EXTERNAL_NAMESPACE=namespace_name</code>. Only one C++ namespace name can be provided with this option. If multiple C++ namespaces are used for serializable types then <code><a class="el" href="dom_8cpp.html">dom.cpp</a></code> must be modified to invoke the following functions:</p>
<ul>
<li><code>name::soap_markelement()</code></li>
<li><code>name::soap_putelement()</code></li>
<li><code>name::soap_getelement()</code></li>
<li><code>name::soap_dupelement()</code></li>
<li><code>name::soap_delelement()</code></li>
</ul>
<p>These should be added for each namespace <code>name</code> and added to the existing invocation of these with <code><a class="el" href="namespace_s_o_a_p___d_o_m___e_x_t_e_r_n_a_l___n_a_m_e_s_p_a_c_e.html">SOAP_DOM_EXTERNAL_NAMESPACE</a>::</code>.</p>
<p>This feature is available for gSOAP 2.8.55 and greater.</p>
<h1><a class="anchor" id="domcpp"></a>
The domcpp command-line tool                                           </h1>
<p>The domcpp command produces high-quality, readable and reusable source code. The generated code can be readily used in your projects to populate XML data and retrieve XML data, thereby saving you substantial time and effort to write DOM API code in C or C++.</p>
<p>The domcpp command-line tool generates C or C++ source code to populate a DOM node graph with the XML data given in an XML file. The command also has an option <code>-i</code> to generate source code to inspect parsed XML by using an XML file as a generic template for this code. And option <code>-p</code> generates efficient source code for XPath queries. Even stand-alone XPath query filter applications can be auto-generated with option <code>-m</code> (for main).</p>
<h2><a class="anchor" id="domcpp-1"></a>
Building and installing domcpp                                       </h2>
<p>You will find domcpp and the XML DOM examples in the gSOAP package in <code>gsoap/samples/dom</code>.</p>
<p>To build domcpp, <a href="http://www.genivia.com/downloads.html">install gSOAP</a> and build domcpp as follows: </p><pre class="fragment">cd gsoap/samples/dom
make domcpp
</pre><p>This builds the command-line tool domcpp in <code>gsoap/samples/dom</code> from where you can use it and/or copy it for use with your projects.</p>
<p>If you do not have the samples built, you can use soapcpp2 from the command line to generate the C++ code required for domcpp: </p><pre class="fragment">cd gsoap/samples/dom
soapcpp2 -CSL ../../import/dom.h
c++ -I../.. -o domcpp domcpp.cpp soapC.cpp ../../dom.cpp ../../stdsoap2.cpp
</pre><p>This builds the domcpp command-line tool.</p>
<p>For users of Windows, visit <a href="http://www.genivia.com/downloads.html">download and installation</a> to download <code>domcpp.exe</code>.</p>
<h2><a class="anchor" id="domcpp-2"></a>
Command-line options                                                 </h2>
<p>The domcpp command takes several options and an optional XML input file: </p><pre class="fragment">domcpp [-c] [-e] [-f%fmt] [-h] [-i] [-l] [-m] [-M] [-n] [-O] [-ofile] [-ppath] [-rroot] [-xcode] [-y] [infile]
</pre><p>where the domcpp command-line options are:</p>
<table class="doxtable">
<tr>
<th>Option </th><th>Description  </th></tr>
<tr>
<td><code>-c</code> </td><td>generate C code instead of C++ </td></tr>
<tr>
<td><code>-e</code> </td><td>add explanatory comments to the generated code </td></tr>
<tr>
<td><code>-f%fmt</code></td><td>use <code>%fmt</code> to format double floats, e.g. <code>-f%lG</code> </td></tr>
<tr>
<td><code>-h</code> </td><td>display help message </td></tr>
<tr>
<td><code>-i</code> </td><td>generate code to inspect DOM node graph parsed from XML input </td></tr>
<tr>
<td><code>-l</code> </td><td>generate code for option <code>-i</code> to store values in local variables </td></tr>
<tr>
<td><code>-m</code> </td><td>generate stand-alone code by adding <code><a class="el" href="dom2calc_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main()</a></code> </td></tr>
<tr>
<td><code>-M</code> </td><td>generate minimal code unadorned with initialization and cleanup </td></tr>
<tr>
<td><code>-n</code> </td><td>generate XML namespace table </td></tr>
<tr>
<td><code>-O</code> </td><td>optimize code by factoring common indices when applicable </td></tr>
<tr>
<td><code>-ofile</code> </td><td>save source code to <code>file</code> </td></tr>
<tr>
<td><code>-ppath</code> </td><td>generate XPath query code for <code>path</code> </td></tr>
<tr>
<td><code>-rroot</code> </td><td>use <code>root</code> instead of root value <code>dom</code> in the generated code </td></tr>
<tr>
<td><code>-xcode</code> </td><td>generate code that executes <code>code</code> for each XPath query result </td></tr>
<tr>
<td><code>-y</code> </td><td>generate code that yields an array <code>y</code> of XPath query results </td></tr>
<tr>
<td><code>infile</code> </td><td>optional XML file to parse </td></tr>
<tr>
<td><code>-</code> </td><td>read XML from standard input </td></tr>
</table>
<p>The domcpp command takes an XML input file <code>infile</code> to generate code to construct a DOM node graph in C/C++ for this XML, or, with option <code>-i</code>, to generate code that reads XML from input and traverses it to inspect its value by using the XML input file <code>infile</code> as a template to match against. For option <code>-i</code>, if you want additional code that uses local variables to store boolean, integer, and floating point values retrieved from the DOM node graph, then also use option <code>-l</code> with option <code>-i</code>.</p>
<p>Use option <code>-c</code> to generate C code instead of C++ and use option <code>-e</code> to add explanatory comments to the generated code.</p>
<p>The domcpp command emits source code to standard output or to the file specified with option <code>-o</code>.</p>
<p>Minimalistic code is generated with option <code>-M</code>, which is useful to automate pasting of the unadorned source code into the source code of your project.</p>
<p>Optimized code is generated with option <code>-O</code> by factoring common array indices and object field names. This produces more elaborate code that is more efficient but may be harder to read and modify. This option has no effect on the code generated with option <code>-i</code>.</p>
<p>The default name of the root value in the generated source code is <code>dom</code>. To change this name use option <code>-r</code>. Do not use the name <code>v</code>, which represents the current value in XPath query C/C++ code. Other variable names to avoid are <code>it</code>, <code>att</code>, <code>elt</code>, and <code>pos</code>, since these are internally used by the generated code.</p>
<p>To include a namespace table in the generated code, use option <code>-n</code>. This option simplifies the use of the DOM API by removing namespace URIs passed to API functions, as the use of qualified tag names will suffice in most cases.</p>
<p>Use option <code>-p</code> to generate code that filters XML data from a source of input with an XPath query <code>path</code>. Option <code>-x</code> specifies XPath query code to execute for each query result. The default action in the generated code is to print each query result value in XML separated by newlines. Option <code>-y</code> yields an XML DOM with root <code>results</code> and each query result stored in a <code>result</code> element. Option <code>-x</code> overrides option <code>-y</code>.</p>
<p>To generate a stand-alone application use option <code>-m</code>. This option is useful for testing XPath query filters given with option <code>-p</code>.</p>
<p>Option <code>-f%fmt</code> sets the floating point double precision format to use in the generated code. By default, domcpp emits floating point numbers with up to 17 digit mantissas to preserve precision. Use <code>-f%lG</code> for the shortest floating point representation.</p>
<h2><a class="anchor" id="domcpp-3"></a>
XPath syntax support for domcpp                                      </h2>
<p>XPath (the XML Path Language), is a query language for selecting nodes from an XML document. A XPath query returns the XML elements and attributes of a DOM node structure of an XML document that match the selection criteria.</p>
<p>An XPath expression specifies a data query to select elements and attributes (and their values) typically starting from the root node, and descending deeper into the node graph to match child nodes.</p>
<p>For example, suppose we have a <code>&lt;store&gt;</code> root element with a number of <code>&lt;book&gt;</code> child elements. Each <code>&lt;book&gt;</code> element has a <code>title</code> attribute with the title text and some other attributes which we will ignore for now. The following XPath query returns the titles of all books in the store: </p><pre class="fragment">/store/book/@title
</pre><p>This example illustrates the most important kind of expression in XPath, which is a <b>location path</b>. A location path consists of a sequence of <b>location steps</b>. Locations steps are separated by '/'. Each step consists of an <b>axis</b> followed by an optional <b>node test</b> and zero or more <b>predicates</b>.</p>
<p>The axis, node tests, and predicates supported by domcpp XPath expressions are listed in the three tables below.</p>
<table class="doxtable">
<tr>
<th>Axis </th><th>Nodes matched and returned  </th></tr>
<tr>
<td><code>/</code> </td><td>document root (when used at the start of the location path) </td></tr>
<tr>
<td><code>//</code> </td><td>descendant or self </td></tr>
<tr>
<td><code>.</code> </td><td>self </td></tr>
<tr>
<td><code>..</code> </td><td>parent node </td></tr>
<tr>
<td><code>@</code> </td><td>attribute node </td></tr>
<tr>
<td><code>tag</code> </td><td>tag name of attributes or elements in the null namespace </td></tr>
<tr>
<td><code>ns:tag</code> </td><td>tag name of attributes or elements in the <code>ns</code> namespace </td></tr>
<tr>
<td><code>*</code> or <code>*:*</code> </td><td>any tag name in any namespace </td></tr>
<tr>
<td><code>*:tag</code> </td><td>tag name in any namespace </td></tr>
<tr>
<td><code>ns:*</code> </td><td>all tags in the <code>ns</code> namespace </td></tr>
</table>
<p>Note that domcpp XPath does not (yet) support the full XPath axis syntax.</p>
<table class="doxtable">
<tr>
<th>Node test </th><th>Nodes matched and returned  </th></tr>
<tr>
<td><code>text()</code> </td><td>text-only child nodes </td></tr>
</table>
<p>A <code>text()</code> node test is useful to select text-only child nodes when its siblings are a mix of text and elements. This mixed content of elements and text is more common in XHTML markup, but not in XML Web service messaging for example.</p>
<p>Zero or more predicates may follow to filter nodes by position, by path, or by a C/C++ expression:</p>
<table class="doxtable">
<tr>
<th>Predicate </th><th>Nodes filtered  </th></tr>
<tr>
<td><code>[n]</code> </td><td>select nodes that are at the n-th position </td></tr>
<tr>
<td><code>[path]</code> </td><td>select nodes if XPath <code>path</code> matches </td></tr>
<tr>
<td><code>[?expr]</code> </td><td>select nodes if C/C++ expression <code>expr</code> is true or nonzero </td></tr>
</table>
<p>Note that domcpp XPath does not (yet) support functions and operators in predicates. Instead, you can use C/C++ expressions to filter nodes where variable <code>v</code> refers to the axis node (i.e. self, which is an <code>xsd__anyType</code> element node or an <code>xsd__anyAttribute</code> attribute node) and the integer variable <code>pos</code> that refers to the query position.</p>
<p>Path subexpressions are grouped with <code>(</code> and <code>)</code>. Grouping is useful to apply predicates to a specific part of the location path. Without grouping, a predicate only applies to the axis that immediately preceeds it. For example, <code>x/y[1]</code> selects the first child element <code>y</code> of all <code>x</code> elements. By contrast, <code>(x/y)[1]</code> selects the first <code>y</code> child element of the first <code>x</code> element that has at least one <code>y</code> child element.</p>
<h2><a class="anchor" id="domcpp-4"></a>
XPath by example                                                     </h2>
<p>Consider the following XML document:</p>
<div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;store&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;  &lt;book</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;    category=&quot;reference&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;    author=&quot;Nigel Rees&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;    title=&quot;Sayings of the Century&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;    price=&quot;8.95&quot; /&gt;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  &lt;book</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;    category=&quot;fiction&quot;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;    author=&quot;Evelyn Waugh&quot;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;    title=&quot;Sword of Honour&quot;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;    price=&quot;12.99&quot; /&gt;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;  &lt;book</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;    category=&quot;fiction&quot;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;    author=&quot;Herman Melville&quot;</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;    title=&quot;Moby Dick&quot;</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;    isbn=&quot;0-553-21311-3&quot;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;    price=&quot;8.99&quot; /&gt;</div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;  &lt;book</div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;    category=&quot;fiction&quot;</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;    author=&quot;J. R. R. Tolkien&quot;</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;    title=&quot;The Lord of the Rings&quot;</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;    isbn=&quot;0-395-19395-8&quot;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;    price=&quot;22.99&quot; /&gt;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;  &lt;bicycle</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;    color=&quot;red&quot;</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;    price=&quot;19.95&quot; /&gt;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;&lt;/store&gt;</div></div><!-- fragment --> </div><p>To match the <code>title</code> of the first book in a <code>store</code>, starting at the root indicated by <code>/</code>, we use the following XPath query expression: </p><pre class="fragment">/store/book[1]/@title
</pre><p>This query returns <code>"Sayings of the Century"</code> when applied to the XML document.</p>
<p>To try the XPath examples yourself, we suggest to create a <code>store.xml</code> file with the above XML and run domcpp from the command line to compile an XPath query as follows: </p><pre class="fragment">cd gsoap/samples/dom
soapcpp2 -CSL ../../import/dom.h
domcpp -o test-dom.cpp -m -p'/store/book[1]/@title'
c++ -I../.. -o test-dom test-dom.cpp soapC.cpp ../../dom.cpp ../../stdsoap2.cpp
./test-dom &lt; store.xml
</pre><p>The <code>soapC.cpp</code> file, and the header files <code>soapStub.h</code> and <code>soapH.h</code>, are generated with the command <code>soapcpp2 -CSL <a class="el" href="dom_8h.html">dom.h</a></code>, which is done just once for all C++ DOM applications. Use soapcpp2 option <code>-c</code> to generate <code>soapC.c</code> for C (with the corresponding <code>soapStub.h</code> and <code>soapH.h</code> in C).</p>
<p>The compiled XPath query is applied to the <code>store.xml</code> document and returns the matches found. Use domcpp option <code>-y</code> to collect and return all matches in an XML document with root <code>results</code>: </p><pre class="fragment">&lt;results&gt;
  &lt;result title="Sayings of the Century"/&gt;
&lt;/results&gt;
</pre><p>To match any tag name of an element or attribute, we use a wildcard <code>*</code>: </p><pre class="fragment">/store/*/@price
</pre><p>This matches and returns the prices of all items in the store. If we want to obtain all <code>price</code> attributes at any level of the node graph, we can also use <code>//</code> called "recursive descent" or simply "recurse" to select descendents (and self when used at the root): </p><pre class="fragment">//@price
</pre><p>This query selects all <code>price</code> attributes in an XML document at any level, including the <code>price</code> attribute of the document root if any. For our example XML store this query returns the prices of all items in the store.</p>
<p>To select all attributes of a node we use a wildcard <code>@*</code>, for example to obtain all attributes of the first book in the store: </p><pre class="fragment">/store/book[1]/@*
</pre><p>We can predicate node selections with criteria based on path location matches. For example, to select items from the store that have an <code>isbn</code> attribute, and then obtain their price, we use a path location predicate <code>[@isbn]</code>: </p><pre class="fragment">/store/*[@isbn]/@price
</pre><p>If we only want to find the first result, we specify a position predicate <code>[1]</code> and apply it to all location steps in the XPath expression: </p><pre class="fragment">/(store/*[@isbn]/@price)[1]
</pre><p>A predicate applies to the axis and its predicates located to the left of the predicate as part of one location step, so we used parenthesis to group the location steps to apply the <code>[1]</code> position predicate.</p>
<p>There can be several ways an XPath query can be formulated. Here is a different one without parenthesis to obtain the same result: </p><pre class="fragment">/store/*[@isbn][@price][1]/@price
</pre><p>This query matches books with both an isbn and price attribute and returns the price of the first match found.</p>
<p>Because all store items are priced in our XML store example, we can also use the following XPath query: </p><pre class="fragment">/store/*[@isbn][1]/@price
</pre><p>However, it is generally better to use more robust XPath queries that are not based on assumptions, such as the previous queries for our XML store that cope with price omissions.</p>
<p>More complex queries can be formulated by embedding C/C++ expressions in the query as predicates with <code>[?expr]</code>. This is an extension of domcpp and not standard XPath expression syntax.</p>
<p>For example, the following XPath query with C++ predicate selects store items with prices under 10.0: </p><pre class="fragment">/store//@price[?(double)v &lt; 10.0]
</pre><p>and in C: </p><pre class="fragment">/store//@price[?soap_att_get_double(v) &lt; 10.0]
</pre><p>We can combine the C/C++ predicate with a path predicate to get books priced under 10.0: </p><pre class="fragment">/store/book[@price[?(double)v &lt; 10.0]]
</pre><p>and to obtain the book titles of these books only: </p><pre class="fragment">/store/book[@price[?(double)v &lt; 10.0]]/@title
</pre><p>XPath queries do not modify the node graph searched. So you do not need to worry about predicates with position indices that are out of bounds or about tag names that refer to non-existent attributes or elements.</p>
<dl class="section warning"><dt>Warning</dt><dd>In this respect we should caution you about using C/C++ expressions that modify DOM nodes, since this may affect the query results in unpredictable ways. For example: <pre class="fragment">//[?(double)v.att("price") &lt; 10.0]
</pre></dd>
<dd>
The <code>att("price")</code> method sets an attribute, not just reads it, so disaster strikes as we visit every node in the DOM node graph to set a price attribute!</dd></dl>
<p>As you can see, C/C++ predicates can inspect the current XPath node by accessing variable <code>v</code>. This variable is either an <code>xsd__anyType</code> DOM element node or an <code>xsd__anyAttribute</code> DOM attribute node, depending on the path. Variable <code>v</code> is a reference in C++ and a pointer in C.</p>
<p>Besides the current node <code>v</code> you can also access the XPath root node <code>dom</code>. Instead of the default root name <code>dom</code>, you can change <code>dom</code> to another name with domcpp option <code>-r</code>. You can also access <code>pos</code> which corresponds to the XPath <code>position()</code> value.</p>
<p>You can access variables and functions in C/C++ predicates, but do not modify the variables <code>it</code> and <code>pos</code> which are internally used by the generated XPath query code.</p>
<p>For example, you can access variable <code>pos</code> (but you should not change it): </p><pre class="fragment">/(store/*[@isbn]/@price)[?pos &gt; 1]
</pre><p>This XPath query returns the price of books with an <code>isbn</code>, but after the first match was discarded by the predicate.</p>
<p>Other temporary variables used internally are a pointer to an attribute <code>att</code> and a pointer to an element <code>elt</code>. You may set and use these as temporaries in the scope of a C/C++ predicate.</p>
<p>The C/C++ predicates are quite powerful and can be used to filter values as shown earlier but also to select attributes and elements by matching their tag name using <code>v,match(tag)</code> in C++ and <code>soap_att_match(v, NULL, tag)</code> or <code>soap_elt_match(v, NULL, tag)</code> in C: </p><pre class="fragment">//book/@*[?v.match(argv[1])]
</pre><p>This assumes that the command-line argument (<code>argv[1]</code>) of the application is a book attribute name. Otherwise, no results are returned.</p>
<p>After compiling the XPath query with </p><pre class="fragment">domcpp -o test-dom.cpp -m -p'//book/@*[?v.match(argv[1])]'
c++ -I../.. -o test-dom test-dom.cpp soapC.cpp ../../dom.cpp ../../stdsoap2.cpp
</pre><p>we can obtain the book titles with: </p><pre class="fragment">./test-dom title &lt; store.xml
</pre><p>Finally, let's use the value of <code>argv</code> to filter products in the store by a given command-line argument price: </p><pre class="fragment">domcpp -m -p'//@price[?(double)v &lt; strtod(argv[1], NULL))]'
</pre><p>and in C: </p><pre class="fragment">domcpp -c -m -p'//@price[?soap_att_get_double(v) &lt; strtod(argv[1], NULL))]'
</pre><p>Note that the <code>strtod</code> function returns the double float value of <code>argv[1]</code> and is repeately called. A more efficient implementation would store the value in a temporary variable and use the temporary in the C/C++ predicate.</p>
<h1><a class="anchor" id="ns"></a>
Understanding XML namespaces                                               </h1>
<p>XML namespaces are commonly used with XML documents that are instances of XML schemas. A full introduction is beyond the scope of this document. We instroduce the basics here to help you understand why XML namespaces are important and how they are used in the C/C++ DOM API of gSOAP.</p>
<p>XML namespace are important when XML documents contain instances of multiple XML schemas. XML elements and attributes that are declared in separate schemas should be distinguishable and their content should be verifyable. Tag name conflicts that may be caused by combining multiple XML schemas to define an XML document can be resolved by binding elements and attributes to specific XML namespaces.</p>
<p>XML elements and attributes are bound to an XML namespace by using a namespace prefix in qualified tag names of elements and attributes. A qualified tag is of the form <code>prefix:name</code>, such that the prefix is bound in the scope of the tag to a namespace URI with an <code>xmlns:prefix="URI"</code> declaration. Unqualified tags can be bound to a namesapce with a <code>xmlns="URI"</code> default namespace declaration.</p>
<p>An XML namespace is a Uniform Resource Identifier (URI). There are two general forms of URI: Uniform Resource Locators (URL) and Uniform Resource Names (URN).</p>
<p>Consider for example the XML document with elements and attributes in three distinct XML namespaces <code>"urn:one"</code>, <code>"urn:two"</code>, and <code>"urn:three"</code>:</p>
<div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;x:e1 a1=&quot;1&quot; xmlns:x=&quot;urn:one&quot; xmlns:y=&quot;urn:two&quot; y:a2=&quot;2&quot;&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;  &lt;e2 xmlns=&quot;urn:three&quot; a3=&quot;3&quot;&gt;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;    &lt;e3 /&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;  &lt;/e2&gt;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;&lt;/x:e1&gt;</div></div><!-- fragment --> </div><p>Element <code>e1</code> is bound to <code>"urn:one"</code>, <code>e2</code> and <code>e3</code> are bound to <code>"urn:three"</code>. Attribute <code>a1</code> has no namespace (it is in the null namespace), <code>a2</code> is bound to <code>"urn:two"</code> and <code>a3</code> is bound to <code>"urn:three"</code>.</p>
<p>A namespace declaration (<code>xmlns</code>) scope extends to all descendants or until redeclared. The <code>x</code> and <code>y</code> prefixes declared in element <code>e1</code> have a scope of visibility in all elements, since <code>e1</code> is the root. The default namespace declaration in element <code>e2</code> has a scope of visibility in element <code>e2</code> and extends to all of its attributes and all of its child elements.</p>
<p>An XML namespace may refer to the defining XML schema by a URL, but often they do not. The URI string itself should be sufficiently unique, which is important to distinguish XML elements and attributes in different XML namespaces. This is similar to C++ namespaces. A unique c++ namespace name suffices (we do not need to know where the source files are located).</p>
<p>The DOM API aims to simplify XML document construction and XML analysis by offering an API that does not require full namespace URIs to passed to the API functions when the URIs are defined in a namespace table. You can simply use qualified tag names to construct XML documents in a DOM and to analyze a DOM after XML parsing. This approach works on the basis of internal normalization so that two prefixes match when their associated URI matches (i.e. prefix names may differ but still match when their URIs match).</p>
<p>Assume we have the following namespace table of <code>{"prefix", "URI"}</code> bindings that includes the three namespace URIs used in our example XML document, but we pick three different prefixes <code>a</code>, <code>b</code>, and <code>c</code>:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>Namespace namespaces[] =</div><div class="line">{</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENV&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-envelope&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENC&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-encoding&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsi&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema-instance&quot;</span>, NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsd&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema&quot;</span>,          <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema&quot;</span>,          NULL},</div><div class="line">  {<span class="stringliteral">&quot;a&quot;</span>,        <span class="stringliteral">&quot;urn:one&quot;</span>},</div><div class="line">  {<span class="stringliteral">&quot;b&quot;</span>,        <span class="stringliteral">&quot;urn:two&quot;</span>},</div><div class="line">  {<span class="stringliteral">&quot;c&quot;</span>,        <span class="stringliteral">&quot;urn:three&quot;</span>},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div></div><!-- fragment --><p>With this table defined globally (or by using <code>soap_set_namespaces()</code> see next section), we can conveniently use qualified tag names with the prefixes <code>a</code>, <code>b</code>, and <code>c</code> to construct and/or match XML elements and attributes in these namespaces, because namespace matching is based on the URI of a prefix.</p>
<p>Therefore, the following qualified tag names match the following elements and attributes in the example XML document:</p>
<table class="doxtable">
<tr>
<th>Tag name </th><th>Matches  </th></tr>
<tr>
<td><code>"a:e1"</code> </td><td>element <code>&lt;x:e1&gt;</code> in namespace scope <code>xmlns:x="urn:one"</code> </td></tr>
<tr>
<td><code>"a1"</code> </td><td>attribute <code>a1</code> in the null namespace </td></tr>
<tr>
<td><code>"b:a2"</code> </td><td>attribute <code>y:a2</code> in namespace scope <code>xmlns:y="urn:two"</code> </td></tr>
<tr>
<td><code>"c:e2"</code> </td><td>element <code>&lt;e2&gt;</code> in namespace scope <code>xmlns="urn:three"</code> </td></tr>
<tr>
<td><code>"c:a3"</code> </td><td>attribute <code>a3</code> in namespace scope <code>xmlns="urn:three"</code> </td></tr>
<tr>
<td><code>"c:e3"</code> </td><td>element <code>e3</code> in namespace scope <code>xmlns="urn:three"</code> </td></tr>
</table>
<p>The choice of prefixes <code>a</code>, <code>b</code>, and <code>c</code> is rather arbitrary. We can pick prefix names for the table as long as they are unique and are valid names (we refer to the XML syntax of "colonized names" and "non-colonized names").</p>
<p>The domcpp option <code>-n</code> includes XML namespaces in a namespace table in the auto-generated code by copying namespace bindings from the XML document analyzed by the tool to a namespace table.</p>
<dl class="section note"><dt>Note</dt><dd>You can also use the wsdl2h tool to retrieve namespaces and declare your own prefix names in <code>typemap.dat</code>. The soapcpp2 tool generates the data binding implementation and a <code>.nsmap</code> file with the namespace bindings.</dd></dl>
<p>You can still use the DOM API without a namespace table or with an incomplete table, but the namespace URIs that are left out from the table must be specified as additional <code>ns</code> parameters in the DOM API functions.</p>
<h1><a class="anchor" id="cpp"></a>
C++ XML DOM API                                                           </h1>
<p>XML is represented as a DOM node graph internally consisting of values (text strings of character data in UTF-8), attribute nodes with tag name and optional namespace URI, and element nodes with optional tag names and optional namespace URI. Tag names are stored in strings of UTF-8. Tag names can be qualified of the form <code>q:tag</code> or unqualified. An element tag name that is NULL represents a text-only node, which will only be present in mixed content of elements and text character data (as in XHTML markup).</p>
<p>XML namespace handling is "smart" in the gSOAP DOM API: the DOM engine matches and stores XML with namespace URIs to ensure that a prefix qualifier is always locally bound to a namespace URI in the node graph. Furthermore, you can use qualified tags when constructing a DOM node instead of the full namespace URI, but only if the prefix and URI are defined in the namespace table (global <code>struct Namespace namesapces[]</code>. When working with wsdl2h and soapcpp2 you should include the soapcpp2-generated <code>.nsmap</code> file with namespace bindings that are applicable to your XML tags.</p>
<h2><a class="anchor" id="cpp-files"></a>
List of C++ files                                                   </h2>
<p>The following files located in the package under <code>gsoap</code> are required to use the C++ DOM API:</p>
<ul>
<li><code>stdsoap2.h</code>: gSOAP engine</li>
<li><code>stdsoap2.cpp</code>: gSOAP engine</li>
<li><code><a class="el" href="dom_8cpp.html">dom.cpp</a></code>: DOM parser and DOM C/C++ API implementation</li>
<li><code><a class="el" href="dom_8h.html">import/dom.h</a></code>: DOM import for data bindings in a .h file for soapcpp2 (do not #include this file in your project builds). Use soapcpp2 <code>-Iimport</code> to specify import path when <code><a class="el" href="dom_8h.html">dom.h</a></code> is imported in a header file for soapcpp2.</li>
</ul>
<p>The gSOAP header file <code><a class="el" href="dom_8h.html">dom.h</a></code> declares the DOM for use in data bindings and should generally be imported with <code>#import</code> in gSOAP header files for the soapcpp2 tool.</p>
<p>You can also run soapcpp2 directly on <code><a class="el" href="dom_8h.html">import/dom.h</a></code> for DOM-only projects. This generates <code>soapStub.h</code>, <code>soapH.h</code> and <code>soapC.cpp</code>. To auto-generate these files, execute: </p><pre class="fragment">soapcpp2 -CSL import/dom.h
</pre><p>Then compile and link the <code><a class="el" href="dom_8cpp.html">dom.cpp</a></code> files listed above with the auto-generated <code>soapC.cpp</code> and <code>stdsoap2.cpp</code>: </p><pre class="fragment">c++ -I../.. -o myapp myapp.cpp soapC.cpp ../../dom.cpp ../../stdsoap2.cpp
</pre><p>Instead of <code>stdsoap2.cpp</code> you can link <code>-lgsoap++.a</code> when installed by the gSOAP package. Or link <code>-lgsoapssl++.a</code> to get both <code>stdsoap2.cpp</code> and <code><a class="el" href="dom_8cpp.html">dom.cpp</a></code> with OpenSSL enabled for HTTPS: </p><pre class="fragment">c++ -DWITH_OPENSSL -I../.. -o myapp myapp.cpp soapC.cpp -lgsoapssl++ -lssl -lcrypto
</pre><p>Note that we compile with <code>-DWITH_OPENSSL</code> and link <code>-lssl</code>, and <code>-lcrypto</code>.</p>
<p>Because XML namespaces are required except for the most simple plain XML applications, you should include the generated <code>.nsmap</code> file:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;soap.nsmap&quot;</span></div></div><!-- fragment --><p>Or define your own namespace table. For example, at a minimum you want a table with SOAP and XSD bindings:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="keyword">struct </span>Namespace namespaces[] =</div><div class="line">{</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENV&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-envelope&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENC&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-encoding&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsi&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema-instance&quot;</span>, NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsd&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema&quot;</span>,          <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema&quot;</span>,          NULL},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div></div><!-- fragment --><p>Then also add entries of the form <code>{"prefix", "URI"}</code> before the last NULL entry to complete the table with xmlns prefix and URI bindings for your XML project.</p>
<h2><a class="anchor" id="cpp-api"></a>
C++ DOM API functions                                                 </h2>
<p>This overview of the DOM API functions refers to the following types of parameters and values, which are used throughout this section:</p>
<table class="doxtable">
<tr>
<th>Name </th><th>Type and value  </th></tr>
<tr>
<td><code>ctx</code> </td><td><code>struct soap *ctx</code> context pointer (manages memory and IO) </td></tr>
<tr>
<td><code>ns</code> </td><td><code>const char *ns</code> XML namespace URI string or NULL </td></tr>
<tr>
<td><code>tag</code> </td><td><code>const char *tag</code> or <code>const wchar_t *tag</code> (un)qualified tag name </td></tr>
<tr>
<td><code>utag</code> </td><td><code>const char *utag</code> or <code>const wchar_t *utag</code> unqualified tag name </td></tr>
<tr>
<td><code>qtag</code> </td><td><code>const char *qtag</code> or <code>const wchar_t *qtag</code> qualified tag name </td></tr>
<tr>
<td><code>patt</code> </td><td>(wide) string (un)qualified tag name pattern with <code>*</code> wildcard(s) </td></tr>
<tr>
<td><code>text</code> </td><td>(wide) string </td></tr>
<tr>
<td><code>node</code> </td><td><code>const void *node</code> pointer to serializable C/C++ data object </td></tr>
<tr>
<td><code>type</code> </td><td><code>SOAP_TYPE_T</code> type identifier of serializable C/C++ data type T </td></tr>
<tr>
<td><code>att</code> </td><td><code>xsd__anyAttribute att</code> DOM attribute node </td></tr>
<tr>
<td><code>elt</code> </td><td><code>xsd__anyType elt</code> DOM element node </td></tr>
<tr>
<td><code>dom</code> </td><td>a DOM node (an element or an attribute node) </td></tr>
<tr>
<td><code>val</code> </td><td>bool, integer, float, or (wide) string </td></tr>
<tr>
<td><code>pos</code> </td><td>element position &gt; 0 (XPath position numbering) </td></tr>
</table>
<p>The API includes functions that take wide strings and normalizes these internally to UTF-8 encoded strings. However, when retrieving tags and text you will only be able to obtain UTF-8 strings. You can convert UTF-8 strings to wide strings that are managed by the context by using:</p>
<ul>
<li><code>int soap_s2wchar(soap *ctx, const char *s, wchar_t **t, long minlen, long maxlen)</code> Convert string <code>s</code> with UTF-8 content to a <code>wchar_t</code> string and set <code>t</code> to point to this string. If no length restrictions are enforced, pass -1 for <code>minlen</code> and <code>maxlen</code>. Returns <code>SOAP_OK</code> (zero) if heap allocation succeeded, or an error code.</li>
<li><code>int soap_s2std__wstring(soap *ctx, const char *s, std::wstring *t, long minlen, long maxlen)</code> Convert string <code>s</code> with UTF-8 content to <code>std::wstring</code> pointed to by <code>t</code>. If no length restrictions are enforced, pass -1 for <code>minlen</code> and <code>maxlen</code>. Returns <code>SOAP_OK</code> (zero) if heap allocation succeeded, or an error code.</li>
</ul>
<h3><a class="anchor" id="cpp-api1"></a>
Creating a DOM root element node</h3>
<p>Creating a DOM node graph starts with creating the root element node using one of the <code>xsd__anyType</code> constructors:</p>
<div class="fragment"><div class="line"><span class="comment">// 8 ways to create a root element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx);                      <span class="comment">// unnamed element node managed by context</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(elt);                      <span class="comment">// copy constructor (shares context and data)</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, utag);                <span class="comment">// element node &lt;utag&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, qtag);                <span class="comment">// element node &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, ns, utag);            <span class="comment">// element node &lt;utag xmlns=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, ns, qtag);            <span class="comment">// element node &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, ns, tag, text);       <span class="comment">// element node as above with a text value</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, ns, tag, node, type); <span class="comment">// element node as above with serializable object</span></div></div><!-- fragment --><p>The third and fourth constructors omit the <code>ns</code> parameter, which is the same as passing a NULL <code>ns</code> parameter.</p>
<p>The fourth constructor is convenient to use to construct an element node that is bound to an XML namespace by using a qualified tag name <code>qtag</code> without specifying the namespace URI with the <code>ns</code> parameter.</p>
<p>To use this approach, you should define the namespace prefix in <code>qtag</code> in a global namespace table, see <a href="#ns">Understanding XML namespaces</a>, and as shown below:</p>
<div class="fragment"><div class="line"><span class="comment">// a global namespace table with {&quot;prefix&quot;, &quot;URI&quot;} xmlns bindings</span></div><div class="line"><span class="keyword">struct </span>Namespace namespaces[] =</div><div class="line">{</div><div class="line">  ...</div><div class="line">  {<span class="stringliteral">&quot;q&quot;</span>, <span class="stringliteral">&quot;urn:example&quot;</span>},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div><div class="line"></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;q:tag&quot;</span>);            <span class="comment">// OK: &quot;q&quot; is in the namespace table</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;bad:tag&quot;</span>);          <span class="comment">// BAD: &quot;bad&quot; is not in the namespace table</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;urn:ok&quot;</span>, <span class="stringliteral">&quot;ok:tag&quot;</span>); <span class="comment">// OK: &quot;ok&quot; is locally scoped in the DOM</span></div></div><!-- fragment --><p>You can also use multiple namespace tables and select the one you want to use with the <code>soap_set_namespaces()</code> function:</p>
<div class="fragment"><div class="line"><span class="comment">// a local (static) namespace table with {&quot;prefix&quot;, &quot;URI&quot;} xmlns bindings</span></div><div class="line"><span class="keyword">struct </span>Namespace my_dom_namespaces[] =</div><div class="line">{</div><div class="line">  ...</div><div class="line">  {<span class="stringliteral">&quot;q&quot;</span>, <span class="stringliteral">&quot;urn:example&quot;</span>},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div><div class="line"></div><div class="line">soap_set_namespaces(ctx, my_dom_namespaces); <span class="comment">// use namespace table for qualified tags</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;q:tag&quot;</span>);              <span class="comment">// OK: &quot;q&quot; is in the namespace table</span></div><div class="line">...</div><div class="line">soap_set_namespaces(ctx, namespaces);        <span class="comment">// restore to global table</span></div></div><!-- fragment --><p>To set or change the tag of an element, use:</p>
<div class="fragment"><div class="line">dom.set(ns, utag); <span class="comment">// element node &lt;utag xmlns=&quot;ns&quot;&gt;</span></div><div class="line">dom.set(ns, qtag); <span class="comment">// element node &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div></div><!-- fragment --><h3><a class="anchor" id="cpp-api2"></a>
Assigning child nodes and values to a DOM node</h3>
<p>After creating a root element node we can start populating the root with attributes, child elements, and values.</p>
<p>To assign a value to a DOM attribute node or element node <code>dom</code>, we can use the the <code><a class="el" href="structsoap__dom__element.html#a94a1eb61b7592b3150f84c7aa4b9a455" title="Set xsd__anyType DOM element namespace URI and tag name. ">xsd__anyType::set()</a></code> and <code><a class="el" href="structsoap__dom__attribute.html#a79264625e3428a501c1215eeee490c57" title="Set this xsd__anyAttribute DOM attribute namespace URI and tag name. ">xsd__anyAttribute::set()</a></code> methods or use the assignment operator as follows:</p>
<div class="fragment"><div class="line"><span class="comment">// 4 ways to assign a value to an element node or to an attribute node</span></div><div class="line">dom.set(val); <span class="comment">// set text character data from bool, integer, float, string value</span></div><div class="line">dom = val;    <span class="comment">// same as above</span></div><div class="line">dom = att;    <span class="comment">// copy attribute node to attribute dom node (shallow, shares data)</span></div><div class="line">dom = elt;    <span class="comment">// copy element node to element dom node (shallow, shares data)</span></div></div><!-- fragment --><p>In addition, element nodes can be assigned serializable objects and data as values, meaning that the object and data will be serialized in place of the element content:</p>
<div class="fragment"><div class="line"><span class="comment">// two ways to assign serializable data to an element node &#39;dom&#39;</span></div><div class="line">dom.set(node, type); <span class="comment">// assign serializable C/C++ object or data to element node</span></div><div class="line">dom = node;          <span class="comment">// assign serializable C/C++ object (object class must have soap_type() method)</span></div></div><!-- fragment --><p>To learn more about embedding serializable objects and data in DOM node graphs, see <a href="#intro-3">Embedding serializable objects and data in DOM element nodes</a>.</p>
<p>To add attributes to the element node <code>xsd__anyType dom</code> we use one of the <code><a class="el" href="structsoap__dom__element.html#a98b830864204c90f40162875ab6574cc" title="Populate this xsd__anyType DOM element node with an attribute node, same as att(NULL, tag), if the attribute does not already exists. ">xsd__anyType::att()</a></code> methods as follows:</p>
<div class="fragment"><div class="line"><span class="comment">// 4 ways to add an attribute to an element node &#39;dom&#39; or extend an attribute list &#39;dom&#39;</span></div><div class="line">dom.att(utag) = val;     <span class="comment">// add attribute utag=&quot;val&quot;</span></div><div class="line">dom.att(qtag) = val;     <span class="comment">// add attribute q:tag=&quot;val&quot; xmlns:q=&quot;ns&quot;</span></div><div class="line">dom.att(ns, utag) = val; <span class="comment">// add attribute _1:utag=&quot;val&quot; xmlns:_1=&quot;ns&quot; with temporary _1, _2, _3, ...</span></div><div class="line">dom.att(ns, qtag) = val; <span class="comment">// add attribute q:tag=&quot;val&quot; xmlns:q=&quot;ns&quot; </span></div></div><!-- fragment --><p>To add child elements to the element node <code>xsd__anyType dom</code> we use one of the <code><a class="el" href="structsoap__dom__element.html#a8e561242ab6bce87520a0f0c303cf456" title="Populate this xsd__anyType DOM element node with an unnamed (tagless) child element node...">xsd__anyType::elt()</a></code> methods and the bracket operator as follows:</p>
<div class="fragment"><div class="line"><span class="comment">// 7 ways to add a child element to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom.<a class="code" href="structsoap__dom__element.html#a8e561242ab6bce87520a0f0c303cf456">elt</a>();         <span class="comment">// add text-only child, unnamed (no tags)</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom.<a class="code" href="structsoap__dom__element.html#a8e561242ab6bce87520a0f0c303cf456">elt</a>(utag);     <span class="comment">// add child element &lt;utag&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom[utag];         <span class="comment">// same as above</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom.<a class="code" href="structsoap__dom__element.html#a8e561242ab6bce87520a0f0c303cf456">elt</a>(qtag);     <span class="comment">// add child element &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom[qtag];         <span class="comment">// same as above</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom.<a class="code" href="structsoap__dom__element.html#a8e561242ab6bce87520a0f0c303cf456">elt</a>(ns, utag); <span class="comment">// add child &lt;tag xmlns=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom.<a class="code" href="structsoap__dom__element.html#a8e561242ab6bce87520a0f0c303cf456">elt</a>(ns, qtag); <span class="comment">// add child &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div></div><!-- fragment --><p>Given the <code>elt</code> reference to a child element of the <code>dom</code> node above, you can use this reference to build more complex node graphs by assigning attributes, child elements, and values at increasingly deeper levels of the tree.</p>
<p>Because element nodes can have multiple children with the same tag name, essentially representing an array, you can use the bracket operator to index the child elements at their relative position among its siblings that have the same tag name. Position indexing starts at one (i.e. <code>[1]</code> XPath style) and child elements are added up to the highest position index used:</p>
<div class="fragment"><div class="line"><span class="comment">// add &#39;array&#39; of three child elements to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; elt = dom[tag]; <span class="comment">// add child (using one of the methods above)</span></div><div class="line">elt[1] = val;                 <span class="comment">// assign val to first child element &lt;tag&gt;</span></div><div class="line">elt[3] = val;                 <span class="comment">// add children &lt;tag&gt; at positions 2 and 3, assign val to the 3rd</span></div></div><!-- fragment --><p>Note that <code>elt[1]</code> refers to <code>elt</code> itself, because indexing starts at 1 (as in XPath). Thus, position index <code>[1]</code> is optional to use.</p>
<p>You can combine these operations and methods in various ways to create more complex DOM node graphs. Let's illustrate this with an example:</p>
<div class="fragment"><div class="line">soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;menu&quot;</span>);</div><div class="line">dom.att(<span class="stringliteral">&quot;id&quot;</span>) = 7;</div><div class="line">dom.att(<span class="stringliteral">&quot;key&quot;</span>) = L<span class="stringliteral">&quot;⌘F&quot;</span>;</div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][1].att(<span class="stringliteral">&quot;value&quot;</span>)   = <span class="stringliteral">&quot;New&quot;</span>;</div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][1].att(<span class="stringliteral">&quot;onclick&quot;</span>) = <span class="stringliteral">&quot;CreateNewDoc()&quot;</span>;</div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][2].att(<span class="stringliteral">&quot;value&quot;</span>)   = <span class="stringliteral">&quot;Open&quot;</span>;</div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][2].att(<span class="stringliteral">&quot;onclick&quot;</span>) = <span class="stringliteral">&quot;OpenDoc()&quot;</span>;</div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][3].att(<span class="stringliteral">&quot;value&quot;</span>)   = <span class="stringliteral">&quot;Close&quot;</span>;</div><div class="line">dom[<span class="stringliteral">&quot;popup&quot;</span>][<span class="stringliteral">&quot;menuitem&quot;</span>][3].att(<span class="stringliteral">&quot;onclick&quot;</span>) = <span class="stringliteral">&quot;CloseDoc()&quot;</span>;</div><div class="line">std::cout &lt;&lt; dom;</div></div><!-- fragment --><p>When executed, this code emits the following XML output on the terminal: </p><pre class="fragment">&lt;menu id="7" key="⌘F"&gt;
  &lt;popup&gt;
    &lt;menuitem value="New" onclick="CreateNewDoc()"/&gt;
    &lt;menuitem value="Open" onclick="OpenDoc()"/&gt;
    &lt;menuitem value="Close" onclick="CloseDoc()"/&gt;
  &lt;/popup&gt;
&lt;/menu&gt;
</pre><p>The <code>xsd__anyAttribute</code> DOM attribute node constructors are identical to the <code>xsd__anyType</code> DOM element node constructors and can be used to create an attribute node or to create a list of attributes.</p>
<p>As an alternative to creating attributes and elements in place, you can also construct attribute and element nodes and add them to other element nodes by using the <code><a class="el" href="structsoap__dom__element.html#af4139d0f6fe42e1e5a3ed720abe821db" title="Add a child element node to this xsd__anyType DOM element node. ">xsd__anyType::add()</a></code> method. For example:</p>
<div class="fragment"><div class="line"><span class="comment">// add an attribute &#39;att&#39; and an element node &#39;elt&#39; to another element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> att(ctx, NULL, <span class="stringliteral">&quot;id&quot;</span>, <span class="stringliteral">&quot;7&quot;</span>); <span class="comment">// id attribute</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> elt(ctx, <span class="stringliteral">&quot;popup&quot;</span>);              <span class="comment">// popup element</span></div><div class="line">dom.add(att).add(elt);                       <span class="comment">// add id attribute and popup as child element</span></div></div><!-- fragment --><p>To create a list of two attributes and add them to an element node <code>dom</code>:</p>
<div class="fragment"><div class="line"><span class="comment">// add a list of attributes &#39;atts&#39; to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> atts(ctx);</div><div class="line">atts.att(<span class="stringliteral">&quot;id&quot;</span>) = 7;</div><div class="line">atts.att(<span class="stringliteral">&quot;key&quot;</span>) = L<span class="stringliteral">&quot;⌘F&quot;</span>;</div><div class="line">dom.adds(atts);</div></div><!-- fragment --><p>Finally, you can use domcpp to generate DOM construction code from a sample XML document.</p>
<h3><a class="anchor" id="cpp-api3"></a>
Matching and retrieving DOM node values and properties</h3>
<p>Given a DOM node graph parsed from an XML document, we can match its tag names and use methods to retrieve values, attribuets, child elements, and properties.</p>
<p>Given a DOM attribute node <code>xsd__anyAttribute dom</code> or element node <code>xsd__anyType dom</code>, you can use the following methods to match and retrieve the node's namespace and tag name:</p>
<div class="fragment"><div class="line"><span class="keywordtype">bool</span> b = dom.match(patt);     <span class="comment">// true if tag matches pattern</span></div><div class="line"><span class="keywordtype">bool</span> b = dom.match(ns, patt); <span class="comment">// true if ns and tag match the patterns</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *s = dom.ns();     <span class="comment">// namespace URI string or NULL if none</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = dom.tag();    <span class="comment">// (un)qualified tag name string, NULL if unnamed</span></div></div><!-- fragment --><p>Given a DOM attribute node <code>xsd__anyAttribute dom</code> or element node <code>xsd__anyType dom</code>, the following methods can be used to retrieve the value of the node's character data content:</p>
<div class="fragment"><div class="line"><span class="keywordtype">bool</span>        b = dom.is_true();    <span class="comment">// true if text is &quot;true&quot; or &quot;1&quot;</span></div><div class="line"><span class="keywordtype">bool</span>        b = dom.is_false();   <span class="comment">// true if text is &quot;false&quot; or &quot;0&quot;</span></div><div class="line">LONG64      n = dom.get_int();    <span class="comment">// 64 bit integer value of text, or 0</span></div><div class="line"><span class="keywordtype">double</span>      x = dom.get_double(); <span class="comment">// double float value of text, or NaN</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = dom.get_text();   <span class="comment">// text string in UTF-8, or NULL if none</span></div></div><!-- fragment --><p>You can also cast an element or attribute node to a bool, an int, a double, or a string to obtain its value. For example:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span>         n = dom; <span class="comment">// integer value cast from text in DOM node, or 0</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = dom; <span class="comment">// text string in UTF-8 of the DOM node, or NULL if none</span></div></div><!-- fragment --><p>Element nodes may contain deserialized objects and data as values, which can be retrieved with one of two methods:</p>
<div class="fragment"><div class="line">T *node = (T*)dom.get_node(SOAP_TYPE_T); <span class="comment">// get deserialized C/C++ object or data of type T, NULL if none</span></div><div class="line"><span class="keywordtype">int</span> type = dom.get_type(&amp;node);          <span class="comment">// get deserialized C/C++ object or data of any type, 0 if none</span></div></div><!-- fragment --><p>To learn more about embedding serializable objects and data in DOM node graphs, see <a href="#intro-3">Embedding serializable objects and data in DOM element nodes</a>.</p>
<p>Given a DOM element node <code>xsd__anyType dom</code>, one of the following methods can be used to retrieve an attribute by its unqualfied tag name (default namespace), by qualified tag name (assuming the prefix is defined in the namespace table), or by namespace and unqualified tag name:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = dom.att_get(utag);     <span class="comment">// get attribute utag, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = dom.att_get(qtag);     <span class="comment">// get attribute q:tag</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = dom.att_get(ns, utag); <span class="comment">// get attribute utag in namespace ns, NULL if none</span></div></div><!-- fragment --><p>The second form is convenient to use to retrieve attributes in namespaces by using a qualified tag name <code>qtag</code> without having to specify the <code>ns</code> namespace URI parameter. This requires the namespace prefix used in <code>qtag</code> to be defined in the global namespace table.</p>
<p>Given a DOM element node <code>xsd__anyType dom</code>, one of the following methods can be used to retrieve a child element by its unqualfied tag name (default namespace), by qualified tag name (assuming the prefix is defined in the namespace table), or by namespace and unqualified tag name:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>();         <span class="comment">// get first text-only child element, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(utag);     <span class="comment">// get first child element &lt;utag&gt;, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(qtag);     <span class="comment">// get first child element &lt;q:tag xmlns:q=&quot;ns&quot;&gt;, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(ns, utag); <span class="comment">// get first child element &lt;s:utag xmlsn:s=&quot;ns&quot;&gt;, NULL if none</span></div><div class="line"></div><div class="line">elt = elt.<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>();                      <span class="comment">// get next matching child element, NULL if none</span></div><div class="line">elt = elt.<a class="code" href="structsoap__dom__element.html#af03d5bc81c9c8ff78db7239d1d2c65f6">get_nth</a>(pos);                    <span class="comment">// get matching child element at pos counting from 1, NULL if none</span></div></div><!-- fragment --><p>The <code>get_next()</code> method can be used in loops to iterate over child elements with the same namespace and tag, as if traversing an array. For example:</p>
<div class="fragment"><div class="line"><span class="comment">// iterate over &lt;menuitem&gt; child elements of element node &#39;dom&#39;</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it = dom.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;menuitem&quot;</span>); it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>())</div><div class="line">  ...</div></div><!-- fragment --><p>To obtain various properties of an <code>xsd__anyType dom</code> element node:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = dom.<a class="code" href="structsoap__dom__element.html#af477895357aad9f7256f4ce9627453ab">parent</a>(); <span class="comment">// parent node, or NULL when root</span></div><div class="line"><span class="keywordtype">size_t</span>          n = dom.<a class="code" href="structsoap__dom__element.html#a1bb4fc85ed309fd21642950b777937cc">depth</a>();  <span class="comment">// depth from the root node (0 is root)</span></div><div class="line"><span class="keywordtype">size_t</span>          n = dom.len();    <span class="comment">// number of siblings that have the same tag name</span></div><div class="line"><span class="keywordtype">size_t</span>        pos = dom.nth();    <span class="comment">// node is at pos with the same tag name as some siblings, or 0 if alone</span></div></div><!-- fragment --><p>The following invariants hold (assuming that pointer dereferences (<code>-&gt;</code>) are verified and valid):</p>
<div class="fragment"><div class="line">dom[tag].match(tag)                   == dom.elt(tag).match(tag) == <span class="keyword">true</span></div><div class="line">dom[tag].parent()                     == dom.elt(tag).parent()   == dom</div><div class="line">dom[tag].tag()                        == dom.elt(tag).tag()      == tag</div><div class="line"></div><div class="line">dom.elt(ns, tag).match(ns, tag)       == dom</div><div class="line">dom.elt(ns, tag).parent()             == dom</div><div class="line">dom.elt(ns, tag).ns()                 == ns</div><div class="line">dom.elt(ns, tag).tag()                == tag</div><div class="line"></div><div class="line">dom.att(tag).match(tag)               == <span class="keyword">true</span></div><div class="line">dom.att(ns, tag).match(ns, tag)       == <span class="keyword">true</span></div><div class="line">dom.att(ns, tag).ns()                 == ns</div><div class="line">dom.att(ns, tag).tag()                == tag</div><div class="line"></div><div class="line">dom.set(val)                          == val  <span class="comment">// by casting to bool, int, float, string</span></div><div class="line"></div><div class="line">dom.elt_get(tag)-&gt;parent()            == dom</div><div class="line">dom.elt_get(tag)-&gt;depth()             == dom.depth() + 1</div><div class="line">dom.elt_get(tag)-&gt;nth()               &lt;= dom.elt_get(tag)-&gt;len()</div><div class="line">dom.elt_get(tag)-&gt;nth()               == 0 <span class="keywordflow">if</span> dom.elt_get(tag)-&gt;len() == 1</div><div class="line">dom.elt_get(tag)-&gt;nth()               == 1 <span class="keywordflow">if</span> dom.elt_get(tag)-&gt;len() &gt;  1</div><div class="line">dom.elt_get(tag)-&gt;get_next()-&gt;nth()   == 2</div><div class="line">dom.elt_get(tag)-&gt;get_nth(pos)-&gt;nth() == pos</div></div><!-- fragment --><h3><a class="anchor" id="cpp-api4"></a>
Traversing a DOM node graph</h3>
<p>Given a DOM node graph, we can traverse its attribute list and its child elements by using the iterators <code><a class="el" href="structsoap__dom__attribute.html#aee33435e6b68edf55f50279ef51ddffb">xsd__anyAttribute::iterator</a></code> and <code><a class="el" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a></code>, respectively:</p>
<div class="fragment"><div class="line"><span class="comment">// print attribute tags</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__attribute.html#aee33435e6b68edf55f50279ef51ddffb">xsd__anyAttribute::iterator</a> it = dom.att_begin(); it != dom.att_end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;@&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; std::endl;</div><div class="line"></div><div class="line"><span class="comment">// print child element tags</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = dom.elt_begin(); it != dom.elt_end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;&lt;&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; <span class="stringliteral">&quot;&gt;&quot;</span> &lt;&lt; std::endl;</div></div><!-- fragment --><p>You can also traverse the entire node graph below a certain DOM element node <code>xsd__anyType dom</code> in depth-first order starting with the current <code>dom</code> node:</p>
<div class="fragment"><div class="line"><span class="comment">// print all element tags in depth-first order</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = dom.begin(); it != dom.end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;&lt;&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; <span class="stringliteral">&quot;&gt; at depth &quot;</span> &lt;&lt; it-&gt;depth() &lt;&lt; std::endl;</div></div><!-- fragment --><h3><a class="anchor" id="cpp-api5"></a>
Searching a DOM node graph</h3>
<p>Given a DOM node graph, we can search its attribute list and its child elements by using a pattern with wildcards <code>*</code> to match namespace and/or tag names, similar to XPath <code>*</code> pattern matching:</p>
<div class="fragment"><div class="line"><span class="comment">// print attribute tags that match *:id (* matches any namespace, including default)</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__attribute.html#aee33435e6b68edf55f50279ef51ddffb">xsd__anyAttribute::iterator</a> it = dom.att_find(<span class="stringliteral">&quot;*:id&quot;</span>); it != dom.att_end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;@&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; std::endl;</div><div class="line"></div><div class="line"><span class="comment">// print element tags in namespace &quot;urn:one&quot; (assuming &quot;x&quot; is &quot;urn:one&quot; in the namespace table)</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = dom.elt_find(<span class="stringliteral">&quot;x:*&quot;</span>); it != dom.elt_end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;&lt;&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; <span class="stringliteral">&quot;&gt;&quot;</span> &lt;&lt; std::endl;</div></div><!-- fragment --><p>The above assumes that a namespace table is used that defines namespace <code>x</code>. Alternatively, you can specify namespace parameters that can be NULL or <code>"*"</code> to match any namespace URI (NULL can be used in place of a <code>"*"</code> pattern):</p>
<div class="fragment"><div class="line"><span class="comment">// print attribute tags that match *:id</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__attribute.html#aee33435e6b68edf55f50279ef51ddffb">xsd__anyAttribute::iterator</a> it = dom.att_find(<span class="stringliteral">&quot;*&quot;</span>, <span class="stringliteral">&quot;id&quot;</span>); it != dom.att_end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;@&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; std::endl;</div><div class="line"></div><div class="line"><span class="comment">// print element tags in namespace &quot;urn:one&quot;</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = dom.elt_find(<span class="stringliteral">&quot;urn:one&quot;</span>, <span class="stringliteral">&quot;*&quot;</span>); it != dom.elt_end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;&lt;&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; <span class="stringliteral">&quot;&lt;&quot;</span> &lt;&lt; std::endl;</div></div><!-- fragment --><p>Patterns for namespaces and tags are not restricted to wildcards <code>*</code>. You can specify parts of a namespace URI or tag name and use one or more <code>*</code> to match the rest.</p>
<p>You can also search the entire node graph below a certain DOM element node in depth-first order starting with the current node:</p>
<div class="fragment"><div class="line"><span class="comment">// find all element nodes with attribute &quot;id&quot; deep in the node graph</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = dom.find(<span class="stringliteral">&quot;@*:id&quot;</span>); it != dom.end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;element &quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; <span class="stringliteral">&quot; has an @id=&quot;</span> &lt;&lt; it-&gt;att_get(<span class="stringliteral">&quot;*:id&quot;</span>)-&gt;get_text() &lt;&lt; std::endl;</div><div class="line"></div><div class="line"><span class="comment">// print all element tags in namespace &quot;urn:one&quot;</span></div><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = dom.find(<span class="stringliteral">&quot;urn:one&quot;</span>, <span class="stringliteral">&quot;*&quot;</span>); it != dom.end(); ++it)</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;&lt;&quot;</span> &lt;&lt; it-&gt;tag() &lt;&lt; <span class="stringliteral">&quot;&gt;&quot;</span> &lt;&lt; std::endl;</div></div><!-- fragment --><h3><a class="anchor" id="cpp-api6"></a>
XML DOM parsing and writing from/to streams</h3>
<p>To parse XML from a stream into a DOM node graph you can use the <code>&gt;&gt;</code> operator on an input stream and a DOM element node:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and parse XML from &#39;cin&#39; into &#39;dom&#39;</span></div><div class="line">soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx);</div><div class="line">std::cin &gt;&gt; dom;</div><div class="line"><span class="keywordflow">if</span> (dom.soap-&gt;error)</div><div class="line">  ... <span class="comment">// check for IO end parse errors</span></div><div class="line">...</div><div class="line">soap_destroy(ctx);</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>To write a DOM node graph in XML to a stream, you can use the <code>&lt;&lt;</code> operator on an output stream and a DOM element node:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and create a &#39;dom&#39;, write its XML to &#39;cout&#39;</span></div><div class="line">soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;store&quot;</span>);</div><div class="line">...</div><div class="line">std::cout &lt;&lt; dom &lt;&lt; std::endl;</div><div class="line"><span class="keywordflow">if</span> (dom.soap-&gt;error)</div><div class="line">  ... <span class="comment">// check for IO errors</span></div><div class="line">...</div><div class="line">soap_destroy(ctx);</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>You can also parse XML from a string into a DOM node graph by using a <code>std::istringstream</code> object:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and parse XML from a string into &#39;dom&#39;</span></div><div class="line">soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line">std::istringstream in;</div><div class="line">in.str(<span class="stringliteral">&quot;&lt;store&gt;&lt;book title=\&quot;Sayings of the Century\&quot;/&gt;&lt;/store&gt;&quot;</span>);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx);</div><div class="line">in &gt;&gt; dom;                      <span class="comment">// parse XML into DOM</span></div><div class="line"><span class="keywordflow">if</span> (dom.soap-&gt;error)</div><div class="line">  ...        <span class="comment">// check for IO and parse errors</span></div><div class="line">...</div><div class="line">soap_destroy(ctx);</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>Likewise, you can write a DOM node graph in XML to a string by using a <code>std::ostringstream</code> object:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and create a &#39;dom&#39;, write its XML to a string</span></div><div class="line">soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line">std::ostringstream out;</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> dom(ctx, <span class="stringliteral">&quot;store&quot;</span>);</div><div class="line">...</div><div class="line">out &lt;&lt; dom;                     <span class="comment">// convert DOM to XML string in UTF-8</span></div><div class="line">...</div><div class="line">soap_destroy(ctx);</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>It is also possible to send and receive XML over HTTP as REST operations as was illustrated in the introduction. To make REST HTTP POST, GET, PUT, and DELETE calls, use <code>soap_dom_call</code>. This function optionally takes a DOM to send or NULL to send nothing and optionally a DOM to receive or NULL to receive nothing (e.g. with HTTP PUT). The function returns <code>SOAP_OK</code> (zero) for success or an error code:</p>
<ul>
<li><code>int soap_dom_call(soap *ctx, const char *URL, const char *action, const xsd__anyType *in, xsd__anyType *out)</code> Make a POST, GET, PUT, DELETE call. Connect to endpoint <code>URL</code> with HTTP SOAPAction <code>action</code> (or NULL) and send request <code>in</code> to server and receive response <code>out</code>. Returns <code>SOAP_OK</code> (zero) or an error code, including HTTP error codes. POST method: pass both <code>in</code> and <code>out</code>. GET method: pass a NULL to <code>in</code>. PUT method: pass a NULL to <code>out</code>. DELETE method: pass both NULL to <code>in</code> and <code>out</code>.</li>
</ul>
<p>This function is overloaded to accept references to the <code>in</code> and <code>out</code> parameters in C++ instead of pointers.</p>
<p>If the server response does not include an HTTP body with XML, then an HTTP error code is returned such as 200. If the server responds with HTTP codes 200, 400 and 500 with an HTTP body with XML, <code>SOAP_OK</code> is returned. The 400 and 500 HTTP status codes may be used to return SOAP/XML Fault messages and are therefore not returned as error codes.</p>
<h1><a class="anchor" id="c"></a>
C XML DOM API                                                               </h1>
<p>XML is represented as a DOM node graph internally consisting of values (text strings of character data in UTF-8), attribute nodes with tag name and optional namespace URI, and element nodes with optional tag names and optional namespace URI. Tag names are stored in strings of UTF-8. Tag names can be qualified of the form <code>q:tag</code> or unqualified. An element tag name that is NULL represents a text-only node, which will only be present in mixed content of elements and text character data (as in XHTML markup).</p>
<p>XML namespace handling is "smart" in the gSOAP DOM API: the DOM engine matches and stores XML with namespace URIs to ensure that a prefix qualifier is always locally bound to a namespace URI in the node graph. Furthermore, you can use qualified tags when constructing a DOM node instead of the full namespace URI, but only if the prefix and URI are defined in the namespace table (global <code>struct Namespace namesapces[]</code>. When working with wsdl2h and soapcpp2 you should include the soapcpp2-generated <code>.nsmap</code> file with namespace bindings that are applicable to your XML tags.</p>
<h2><a class="anchor" id="c-files"></a>
List of C files                                                       </h2>
<p>The following files located in the package under <code>gsoap</code> are required to use the C DOM API:</p>
<ul>
<li><code>stdsoap2.h</code>: gSOAP engine</li>
<li><code>stdsoap2.c</code>: gSOAP engine</li>
<li><code>dom.c</code>: DOM parser and DOM C/C++ API implementation</li>
<li><code><a class="el" href="dom_8h.html">import/dom.h</a></code>: DOM import for data bindings in a .h file for soapcpp2 (do not #include this file in your project builds) Use soapcpp2 <code>-Iimport</code> to specify import path when <code><a class="el" href="dom_8h.html">dom.h</a></code> is imported in a header file for soapcpp2.</li>
</ul>
<p>The gSOAP header file <code><a class="el" href="dom_8h.html">dom.h</a></code> declares the DOM for use in data bindings and should generally be imported with <code>#import</code> in gSOAP header files for the soapcpp2 tool.</p>
<p>You can also run soapcpp2 directly on <code><a class="el" href="dom_8h.html">import/dom.h</a></code> for DOM-only projects. This generates <code>soapStub.h</code>, <code>soapH.h</code> and <code>soapC.cpp</code>. To auto-generate these files, execute: </p><pre class="fragment">soapcpp2 -c -CSL import/dom.h
</pre><p>Then compile and link the <code>dom.c</code> files listed above with the auto-generated <code>soapC.c</code> and <code>stdsoap2.c</code>: </p><pre class="fragment">cc -I../.. -o myapp myapp.c soapC.c ../../dom.c ../../stdsoap2.c
</pre><p>Instead of <code>stdsoap2.c</code> you can link <code>-lgsoap.a</code> when installed by the gSOAP package. Or link <code>-lgsoapssl.a</code> to get both <code>stdsoap2.c</code> and <code>dom.c</code> with OpenSSL enabled for HTTPS: </p><pre class="fragment">cc -DWITH_OPENSSL -I../.. -o myapp myapp.c soapC.c -lgsoapssl -lssl -lcrypto
</pre><p>Note that we compile with <code>-DWITH_OPENSSL</code> and link <code>-lssl</code>, and <code>-lcrypto</code>.</p>
<p>Because XML namespaces are required except for the most simple plain XML applications, you should include the generated <code>.nsmap</code> file:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;soap.nsmap&quot;</span></div></div><!-- fragment --><p>Or define your own namespace table. For example, at a minimum you want a table with SOAP and XSD bindings:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"><span class="keyword">struct </span>Namespace namespaces[] =</div><div class="line">{</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENV&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-envelope&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENC&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-encoding&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsi&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema-instance&quot;</span>, NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsd&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema&quot;</span>,          <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema&quot;</span>,          NULL},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div></div><!-- fragment --><p>Then also add entries of the form <code>{"prefix", "URI"}</code> before the last NULL entry to complete the table with xmlns prefix and URI bindings for your XML project.</p>
<h2><a class="anchor" id="c-api"></a>
C DOM API functions                                                     </h2>
<p>This overview of the DOM API functions refers to the following types of parameters and values, which are used throughout this section:</p>
<table class="doxtable">
<tr>
<th>Name </th><th>Type and value  </th></tr>
<tr>
<td><code>ctx</code> </td><td><code>struct soap *ctx</code> context pointer (manages memory and IO) </td></tr>
<tr>
<td><code>ns</code> </td><td><code>const char *ns</code> XML namespace URI string or NULL </td></tr>
<tr>
<td><code>tag</code> </td><td><code>const char *tag</code> or <code>const wchar_t *tag</code> (un)qualified tag name </td></tr>
<tr>
<td><code>utag</code> </td><td><code>const char *utag</code> or <code>const wchar_t *utag</code> unqualified tag name </td></tr>
<tr>
<td><code>qtag</code> </td><td><code>const char *qtag</code> or <code>const wchar_t *qtag</code> qualified tag name </td></tr>
<tr>
<td><code>patt</code> </td><td>(wide) string (un)qualified tag name pattern with <code>*</code> wildcard(s) </td></tr>
<tr>
<td><code>text</code> </td><td>(wide) string </td></tr>
<tr>
<td><code>node</code> </td><td><code>const void *node</code> pointer to serializable C/C++ data object </td></tr>
<tr>
<td><code>type</code> </td><td><code>SOAP_TYPE_T</code> type identifier of serializable C/C++ data type T </td></tr>
<tr>
<td><code>att</code> </td><td><code>xsd__anyAttribute *att</code> DOM attribute node pointer </td></tr>
<tr>
<td><code>elt</code> </td><td><code>xsd__anyType *elt</code> DOM element node pointer </td></tr>
<tr>
<td><code>dom</code> </td><td>a DOM node (a pointer to an element or an attribute node) </td></tr>
<tr>
<td><code>val</code> </td><td>bool, integer, float, or (wide) string </td></tr>
<tr>
<td><code>pos</code> </td><td>element position &gt; 0 (XPath position numbering) </td></tr>
</table>
<p>The API includes functions that take wide strings and normalizes these internally to UTF-8 encoded strings. However, when retrieving tags and text you will only be able to obtain UTF-8 strings. You can convert UTF-8 strings to wide strings that are managed by the context by using:</p>
<ul>
<li><code>int soap_s2wchar(struct soap *ctx, const char *s, wchar_t **t, long minlen, long maxlen)</code> Convert string <code>s</code> with UTF-8 content to a <code>wchar_t</code> string and set <code>t</code> to point to this string. If no length restrictions are enforced, pass -1 for <code>minlen</code> and <code>maxlen</code>. Returns <code>SOAP_OK</code> (zero) if heap allocation succeeded, or an error code.</li>
</ul>
<h3><a class="anchor" id="c-api1"></a>
Creating a DOM root element node</h3>
<p>Creating a DOM node graph starts with creating the root element node using one of the <code>xsd__anyType</code> allocators:</p>
<div class="fragment"><div class="line"><span class="comment">// 4 ways to create a root element node pointer &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, utag); <span class="comment">// element node &lt;utag&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, qtag); <span class="comment">// element node &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, ns, utag);   <span class="comment">// element node &lt;utag xmlns=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, ns, qtag);   <span class="comment">// element node &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div></div><!-- fragment --><p>For wide string tags, use <code>soap_elt_new_w(ctx, ns, tag)</code>. All C API functions that support wide strings end in <code>_w</code> by convention.</p>
<p>The second function call in the list is convenient to use to construct an element node that is bound to an XML namespace by using a qualified tag name <code>qtag</code> while specifying the namespace URI as NULL.</p>
<p>To use this approach, you should define the namespace prefix in <code>qtag</code> in a global namespace table, see <a href="#ns">Understanding XML namespaces</a>, and as shown below:</p>
<div class="fragment"><div class="line"><span class="comment">// a global namespace table with {&quot;prefix&quot;, &quot;URI&quot;} xmlns bindings</span></div><div class="line"><span class="keyword">struct </span>Namespace namespaces[] =</div><div class="line">{</div><div class="line">  ...</div><div class="line">  {<span class="stringliteral">&quot;q&quot;</span>, <span class="stringliteral">&quot;urn:example&quot;</span>},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div><div class="line"></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;q:tag&quot;</span>);      <span class="comment">// OK: &quot;q&quot; is in the namespace table</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;bad:tag&quot;</span>);    <span class="comment">// BAD: &quot;bad&quot; is not in the namespace table</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, <span class="stringliteral">&quot;urn:ok&quot;</span>, <span class="stringliteral">&quot;ok:tag&quot;</span>); <span class="comment">// OK: &quot;ok&quot; is locally scoped in the DOM</span></div></div><!-- fragment --><p>You can also use multiple namespace tables and select the one you want to use with the <code>soap_set_namespaces()</code> function:</p>
<div class="fragment"><div class="line"><span class="comment">// a local (static) namespace table with {&quot;prefix&quot;, &quot;URI&quot;} xmlns bindings</span></div><div class="line"><span class="keyword">struct </span>Namespace my_dom_namespaces[] =</div><div class="line">{</div><div class="line">  ...</div><div class="line">  {<span class="stringliteral">&quot;q&quot;</span>, <span class="stringliteral">&quot;urn:example&quot;</span>},</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div><div class="line"></div><div class="line">soap_set_namespaces(ctx, my_dom_namespaces);          <span class="comment">// use namespace table for qualified tags</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;q:tag&quot;</span>); <span class="comment">// OK: &quot;q&quot; is in the namespace table</span></div><div class="line">...</div><div class="line">soap_set_namespaces(ctx, namespaces);                 <span class="comment">// restore to global table</span></div></div><!-- fragment --><p>To set or change the tag of an element, use:</p>
<div class="fragment"><div class="line"><a class="code" href="dom_8cpp.html#a246e8a474b5d4ab7a93c536209bc0eb1">soap_elt_set</a>(dom, ns, utag); <span class="comment">// element node &lt;utag xmlns=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="dom_8cpp.html#a246e8a474b5d4ab7a93c536209bc0eb1">soap_elt_set</a>(dom, ns, qtag); <span class="comment">// element node &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div></div><!-- fragment --><h3><a class="anchor" id="c-api2"></a>
Assigning child nodes and values to a DOM node</h3>
<p>After creating a root element node we can start populating the root with attributes, child elements, and values.</p>
<p>To assign a value to a DOM element node <code>dom</code> you can use one the the following functions:</p>
<div class="fragment"><div class="line"><span class="comment">// 6 ways to assign a value to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="dom_8cpp.html#a62e9d0e96fbc3a6f87ea8c973e6a535f">soap_elt_bool</a>(dom, val);   <span class="comment">// set text to boolean &quot;false&quot; or &quot;true&quot;</span></div><div class="line"><a class="code" href="dom_8cpp.html#aca27dd1369a7b124f5020357cb22163c">soap_elt_int</a>(dom, val);    <span class="comment">// set text to integer (64 bit)</span></div><div class="line"><a class="code" href="dom_8cpp.html#a86fcd55e58aba40d0f1db75845d14922">soap_elt_double</a>(dom, val); <span class="comment">// set text to (double) float</span></div><div class="line"><a class="code" href="dom_8cpp.html#ab74f18ec0f11666fd99f95813b7b5968">soap_elt_text</a>(dom, val);   <span class="comment">// set text with UTF-8 string content</span></div><div class="line"><a class="code" href="dom_8cpp.html#a12d6b7f4fc0d0f52016d19767056703d">soap_elt_text_w</a>(dom, val); <span class="comment">// set text with wide string content</span></div><div class="line"><a class="code" href="dom_8cpp.html#ad633e185957e6a4a8d4ce04e74db0792">soap_elt_copy</a>(dom, elt);   <span class="comment">// copy element node to element dom node (shallow, shares data)</span></div></div><!-- fragment --><p>You can use similar functions for DOM attribute nodes, altough you do not need these to populate DOM element nodes because it is easier to use the <code><a class="el" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131" title="Populate xsd__anyType DOM element node with an attribute node, if the attribute does not already exis...">soap_att()</a></code> function shown further below:</p>
<div class="fragment"><div class="line"><span class="comment">// 6 ways to assign a value to an attribute node &#39;dom&#39;</span></div><div class="line"><a class="code" href="dom_8cpp.html#a97ca7c7ec176abf9f2e0f7f6f86371f6">soap_att_bool</a>(dom, val);   <span class="comment">// set text to boolean &quot;false&quot; or &quot;true&quot;</span></div><div class="line"><a class="code" href="dom_8cpp.html#adba6b7c98ea57dc2ef130eefee2273cd">soap_att_int</a>(dom, val);    <span class="comment">// set text to integer (64 bit)</span></div><div class="line"><a class="code" href="dom_8cpp.html#ad4de59216ad5abefbe89d06a6d11da1a">soap_att_double</a>(dom, val); <span class="comment">// set text to (double) float</span></div><div class="line"><a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(dom, val);   <span class="comment">// set text with UTF-8 string content</span></div><div class="line"><a class="code" href="dom_8cpp.html#adedd2e1b886d9f58e88701106302c601">soap_att_text_w</a>(dom, val); <span class="comment">// set text with wide string content</span></div><div class="line"><a class="code" href="dom_8cpp.html#a6a3c262b165e913a9f5d44872c5076cf">soap_att_copy</a>(dom, elt);   <span class="comment">// copy attribute node to attribute dom node (shallow, shares data)</span></div></div><!-- fragment --><p>In addition, element nodes can be assigned serializable objects and data as values, meaning that the object and data will be serialized in place of the element content:</p>
<div class="fragment"><div class="line"><span class="comment">// assign serializable data to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="dom_8cpp.html#ad79af5888bcbc783e4dc95f8906a2d03">soap_elt_node</a>(dom, node, type); <span class="comment">// assign serializable C data to element node</span></div></div><!-- fragment --><p>To learn more about embedding serializable objects and data in DOM node graphs, see <a href="#intro-3">Embedding serializable objects and data in DOM element nodes</a>.</p>
<p>To add attributes to an element node <code>dom</code> you can use one of the following functions (use <code>soap_att_w</code> for wide string tags):</p>
<div class="fragment"><div class="line"><span class="comment">// 4 ways to add an attribute to an element node &#39;dom&#39; or extend an attribute list &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, NULL, utag); <span class="comment">// add attribute utag=&quot;val&quot;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, NULL, qtag); <span class="comment">// add attribute q:tag=&quot;val&quot; xmlns:q=&quot;ns&quot;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, ns, utag);   <span class="comment">// add attribute _1:utag=&quot;val&quot; xmlns:_1=&quot;ns&quot; with temporary _1, _2, _3, ...</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, ns, qtag);   <span class="comment">// add attribute q:tag=&quot;val&quot; xmlns:q=&quot;ns&quot; </span></div></div><!-- fragment --><p>You can then set the value of the attribute <code>att</code> as was shown earlier.</p>
<p>To add child elements to the element node <code>dom</code> we use one of the following functions (use <code>soap_elt_w</code> for wide string tags):</p>
<div class="fragment"><div class="line"><span class="comment">// 5 ways to add a child element to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, NULL); <span class="comment">// add text-only child, unnamed (no tags)</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, utag); <span class="comment">// add child element &lt;utag&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, qtag); <span class="comment">// add child element &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, ns, utag);   <span class="comment">// add child &lt;tag xmlns=&quot;ns&quot;&gt;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, ns, qtag);   <span class="comment">// add child &lt;q:tag xmlns:q=&quot;ns&quot;&gt;</span></div></div><!-- fragment --><p>Given the <code>elt</code> pointer to a child element node of the <code>dom</code> node, you can use the pointer to build more complex node graphs by assigning attributes, child elements, and values at increasingly deeper levels of the tree.</p>
<p>Because element nodes can have multiple children with the same tag name, essentially representing an array, you can index the child elements at their relative position among its siblings that have the same tag name. Position indexing starts at one (i.e. XPath style) and child elements are added up to the highest position index used:</p>
<div class="fragment"><div class="line"><span class="comment">// add &#39;array&#39; of three child elements to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, tag); <span class="comment">// add child (using one of the functions above)</span></div><div class="line"><a class="code" href="dom_8cpp.html#aca27dd1369a7b124f5020357cb22163c">soap_elt_int</a>(<a class="code" href="dom_8cpp.html#a18e7547e77a2d2a1c2be9f64f808b69c">soap_nth</a>(elt, 1), val);          <span class="comment">// assign val to first child element &lt;tag&gt;</span></div><div class="line"><a class="code" href="dom_8cpp.html#aca27dd1369a7b124f5020357cb22163c">soap_elt_int</a>(<a class="code" href="dom_8cpp.html#a18e7547e77a2d2a1c2be9f64f808b69c">soap_nth</a>(elt, 3), val);          <span class="comment">// add children &lt;tag&gt; at positions 2 and 3, assign val to the 3rd</span></div></div><!-- fragment --><p>The combination <code>soap_nth(soap_elt(dom, ns, tag), pos)</code> can be shortend to <code>soap_nth_elt(dom, ns, tag, pos)</code>.</p>
<p>Note that <code>soap_nth(elt, 1)</code> refers to <code>elt</code> itself, because indexing starts at 1 (as in XPath).</p>
<p>You can combine these operations in various ways to create more complex DOM node graphs. Let's illustrate this with an example:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;menu&quot;</span>);</div><div class="line"><a class="code" href="dom_8cpp.html#adba6b7c98ea57dc2ef130eefee2273cd">soap_att_int</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, NULL, <span class="stringliteral">&quot;id&quot;</span>), 7);</div><div class="line"><a class="code" href="dom_8cpp.html#adedd2e1b886d9f58e88701106302c601">soap_att_text_w</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;⌘F&quot;</span>);</div><div class="line">{</div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom_popup = <a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, <span class="stringliteral">&quot;popup&quot;</span>);</div><div class="line">  {</div><div class="line">    <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom_popup_menuitem = <a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(dom_popup, NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 1);</div><div class="line">    <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom_popup_menuitem, NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;New&quot;</span>);</div><div class="line">    <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom_popup_menuitem, NULL, <span class="stringliteral">&quot;onclick&quot;</span>), <span class="stringliteral">&quot;CreateNewDoc()&quot;</span>);</div><div class="line">  }</div><div class="line">  {</div><div class="line">    <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom_popup_menuitem = <a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(dom_popup, NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 2);</div><div class="line">    <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom_popup_menuitem, NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;Open&quot;</span>);</div><div class="line">    <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom_popup_menuitem, NULL, <span class="stringliteral">&quot;onclick&quot;</span>), <span class="stringliteral">&quot;OpenDoc()&quot;</span>);</div><div class="line">  }</div><div class="line">  {</div><div class="line">    <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom_popup_menuitem = <a class="code" href="dom_8cpp.html#a38ab3d8bbbab82723b7d6c9608653bf8">soap_nth_elt</a>(dom_popup, NULL, <span class="stringliteral">&quot;menuitem&quot;</span>, 3);</div><div class="line">    <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom_popup_menuitem, NULL, <span class="stringliteral">&quot;value&quot;</span>), <span class="stringliteral">&quot;Close&quot;</span>);</div><div class="line">    <a class="code" href="dom_8cpp.html#a07795d417ae59559dea2c2200376aa5e">soap_att_text</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom_popup_menuitem, NULL, <span class="stringliteral">&quot;onclick&quot;</span>), <span class="stringliteral">&quot;CloseDoc()&quot;</span>);</div><div class="line">  }</div><div class="line">}</div><div class="line"><a class="code" href="dom_8cpp.html#afd8f56d71b8afa28ea394033b440ca2f">soap_write_xsd__anyType</a>(ctx, dom);</div></div><!-- fragment --><p>When executed, this code emits the following XML output on the terminal: </p><pre class="fragment">&lt;menu id="7" key="⌘F"&gt;
  &lt;popup&gt;
    &lt;menuitem value="New" onclick="CreateNewDoc()"/&gt;
    &lt;menuitem value="Open" onclick="OpenDoc()"/&gt;
    &lt;menuitem value="Close" onclick="CloseDoc()"/&gt;
  &lt;/popup&gt;
&lt;/menu&gt;
</pre><p>The <code>xsd__anyAttribute</code> DOM attribute node allocation functions are identical to the <code>xsd__anyType</code> DOM element node allocation functions and can be used to create an attribute node or to create a list of attributes.</p>
<p>As an alternative to creating attributes and elements in place, you can also construct attribute and element nodes and add them to other element nodes:</p>
<div class="fragment"><div class="line"><span class="comment">// add an attribute &#39;att&#39; and an element node &#39;elt&#39; to another element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a749aa455cea1dcbca610f89736f61407">soap_att_new</a>(ctx, NULL, <span class="stringliteral">&quot;id&quot;</span>);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;popup&quot;</span>);</div><div class="line"><a class="code" href="dom_8cpp.html#adba6b7c98ea57dc2ef130eefee2273cd">soap_att_int</a>(att, 7);</div><div class="line"><a class="code" href="dom_8cpp.html#adb8f1d8119f00c83eefc071f3cbde29e">soap_add_att</a>(dom, att);</div><div class="line"><a class="code" href="dom_8cpp.html#a8868a8b0a1151e52e777efd4f7f28716">soap_add_elt</a>(dom, elt);</div></div><!-- fragment --><p>To create a list of two attributes and add them to an element node <code>dom</code>:</p>
<div class="fragment"><div class="line"><span class="comment">// add a list of attributes &#39;atts&#39; to an element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *atts = <a class="code" href="dom_8cpp.html#a749aa455cea1dcbca610f89736f61407">soap_att_new</a>(ctx, NULL, NULL);</div><div class="line"><a class="code" href="dom_8cpp.html#adba6b7c98ea57dc2ef130eefee2273cd">soap_att_int</a>(<a class="code" href="dom_8cpp.html#af2a882f9ac0795c6c631071ac78ace37">soap_att_add</a>(atts, NULL, <span class="stringliteral">&quot;id&quot;</span>), 7);</div><div class="line"><a class="code" href="dom_8cpp.html#adedd2e1b886d9f58e88701106302c601">soap_att_text_w</a>(<a class="code" href="dom_8cpp.html#af2a882f9ac0795c6c631071ac78ace37">soap_att_add</a>(atts, NULL, <span class="stringliteral">&quot;key&quot;</span>), L<span class="stringliteral">&quot;⌘F&quot;</span>);</div><div class="line"><a class="code" href="dom_8cpp.html#a9d596d0289f49c8707b8e8c014377634">soap_add_atts</a>(dom, atts);</div></div><!-- fragment --><p>Finally, you can use domcpp to generate DOM construction code from a sample XML document.</p>
<h3><a class="anchor" id="c-api3"></a>
Matching and retrieving DOM node values and properties</h3>
<p>Given a DOM node graph parsed from an XML document, we can match its tag names and use functions to retrieve values, attribuets, child elements, and properties.</p>
<p>Given a DOM element node <code>dom</code>, you can use the following functions to match and retrieve the node's namespace and tag name:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> b = <a class="code" href="dom_8cpp.html#a53df62a627353cf06310a38b6c7046a0">soap_elt_match</a>(dom, NULL, patt); <span class="comment">// true if tag matches pattern</span></div><div class="line"><span class="keywordtype">int</span> b = <a class="code" href="dom_8cpp.html#a53df62a627353cf06310a38b6c7046a0">soap_elt_match</a>(dom, ns, patt);   <span class="comment">// true if ns and tag match the patterns</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *s = <a class="code" href="dom_8cpp.html#a77234d674c351892ad534f6c7fef6422">soap_elt_get_ns</a>(dom));   <span class="comment">// namespace URI string or NULL if none</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(dom);   <span class="comment">// (un)qualified tag name string, NULL if unnamed</span></div></div><!-- fragment --><p>Similar for attribute node <code>dom</code>:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> b = <a class="code" href="dom_8cpp.html#afb4017b8f4bb5a2953167bc61ee937e9">soap_att_match</a>(dom, NULL, patt); <span class="comment">// true if tag matches pattern</span></div><div class="line"><span class="keywordtype">int</span> b = <a class="code" href="dom_8cpp.html#afb4017b8f4bb5a2953167bc61ee937e9">soap_att_match</a>(dom, ns, patt);   <span class="comment">// true if ns and tag match the patterns</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *s = <a class="code" href="dom_8cpp.html#a844c720c8dfa2b0bd9071aeb42ede82e">soap_att_get_ns</a>(dom));   <span class="comment">// namespace URI string or NULL if none</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = <a class="code" href="dom_8cpp.html#af0d695aea7a6aadff918ec4150da3536">soap_att_get_tag</a>(dom);   <span class="comment">// (un)qualified tag name string, NULL if unnamed</span></div></div><!-- fragment --><p>Given a DOM element node <code>dom</code>, the following functions can be used to retrieve the value of the node's character data content:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span>         b = <a class="code" href="dom_8cpp.html#a9cbf116d1f06c0da8681def545653ec1">soap_elt_is_true</a>(dom);    <span class="comment">// true if text is &quot;true&quot; or &quot;1&quot;</span></div><div class="line"><span class="keywordtype">int</span>         b = <a class="code" href="dom_8cpp.html#aa5636c832fa589887148f4d4da834ade">soap_elt_is_false</a>(dom);   <span class="comment">// true if text is &quot;false&quot; or &quot;0&quot;</span></div><div class="line">LONG64      n = <a class="code" href="dom_8cpp.html#ad9b8fc1a25f13e99aed9a39029c312f2">soap_elt_get_int</a>(dom));   <span class="comment">// 64 bit integer value of text, or 0</span></div><div class="line"><span class="keywordtype">double</span>      x = <a class="code" href="dom_8cpp.html#a54a2b1549d812e70bcfa0e197d02ff1e">soap_elt_get_double</a>(dom); <span class="comment">// double float value of text, or NaN</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = <a class="code" href="dom_8cpp.html#ab0c417563dfe48a282ac4265b36222c8">soap_elt_get_text</a>(dom));  <span class="comment">// text string in UTF-8, or NULL if none</span></div></div><!-- fragment --><p>Similar for attribute node <code>dom</code>:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span>         b = <a class="code" href="dom_8cpp.html#a7047e3ea7b126cbb34f23d8d8208d91b">soap_att_is_true</a>(dom);    <span class="comment">// true if text is &quot;true&quot; or &quot;1&quot;</span></div><div class="line"><span class="keywordtype">int</span>         b = <a class="code" href="dom_8cpp.html#aa62b97f97e2a646ec2e45551b931d9a8">soap_att_is_false</a>(dom);   <span class="comment">// true if text is &quot;false&quot; or &quot;0&quot;</span></div><div class="line">LONG64      n = <a class="code" href="dom_8cpp.html#a18360245b72c1b17fe20191a5c72cb71">soap_att_get_int</a>(dom));   <span class="comment">// 64 bit integer value of text, or 0</span></div><div class="line"><span class="keywordtype">double</span>      x = <a class="code" href="dom_8cpp.html#afa9cbeee9da3caa1375d7dfd1e9db158">soap_att_get_double</a>(dom); <span class="comment">// double float value of text, or NaN</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *t = <a class="code" href="dom_8cpp.html#a6810a34c76ca237fe7c40169ef1cffa2">soap_att_get_text</a>(dom));  <span class="comment">// text string in UTF-8, or NULL if none</span></div></div><!-- fragment --><p>Element nodes may contain deserialized objects and data as values, which can be retrieved with one of two methods:</p>
<div class="fragment"><div class="line">T *node = (T*)<a class="code" href="dom_8cpp.html#ae41e24810273d2be8066085113570b12">soap_elt_get_node</a>(dom, SOAP_TYPE_T); <span class="comment">// get deserialized C data of type T, NULL if none</span></div><div class="line"><span class="keywordtype">int</span> type = <a class="code" href="dom_8cpp.html#a7924e4ddc2c1993c4d299846f728c88a">soap_elt_get_type</a>(dom, &amp;node);          <span class="comment">// get deserialized C data of any type, 0 if none</span></div></div><!-- fragment --><p>To learn more about embedding serializable objects and data in DOM node graphs, see <a href="#intro-3">Embedding serializable objects and data in DOM element nodes</a>.</p>
<p>Given a DOM element node <code>dom</code>, one of the following methods can be used to retrieve an attribute by its unqualfied tag name (has no namespace), by qualified tag name (assuming the prefix is defined in the namespace table), or by namespace and unqualified tag name:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a4176879ce7738f27b9c4c744b2b8043c">soap_att_get</a>(dom, NULL, utag); <span class="comment">// get attribute utag, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a4176879ce7738f27b9c4c744b2b8043c">soap_att_get</a>(dom, NULL, qtag); <span class="comment">// get attribute q:tag</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *att = <a class="code" href="dom_8cpp.html#a4176879ce7738f27b9c4c744b2b8043c">soap_att_get</a>(dom, ns, utag);   <span class="comment">// get attribute utag in namespace ns, NULL if none</span></div></div><!-- fragment --><p>The second form is convenient to use to retrieve attributes in namespaces by using a qualified tag name <code>qtag</code> without having to specify the <code>ns</code> namespace URI parameter. This requires the namespace prefix used in <code>qtag</code> to be defined in the global namespace table.</p>
<p>Given a DOM element node <code>dom</code>, one of the following functions can be used to retrieve a child element by its unqualfied tag name (has no namespace), by qualified tag name (assuming the prefix is defined in the namespace table), or by namespace and unqualified tag name:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, NULL, NULL); <span class="comment">// get first text-only child element, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, NULL, utag); <span class="comment">// get first child element &lt;utag&gt;, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, NULL, qtag); <span class="comment">// get first child element &lt;q:tag xmlns:q=&quot;ns&quot;&gt;, NULL if none</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, utag);   <span class="comment">// get first child element &lt;s:tag xmlsn:s=&quot;ns&quot;&gt;, NULL if none</span></div><div class="line"></div><div class="line">elt = <a class="code" href="dom_8cpp.html#aa2b4d8e388f66603b033a4c6e7a08303">soap_elt_get_next</a>(elt);                      <span class="comment">// get next matching child element, NULL if none</span></div><div class="line">elt = <a class="code" href="dom_8cpp.html#a76f66c5f1941c3330e10ef99a5604319">soap_elt_get_nth</a>(elt, pos);                  <span class="comment">// get matching child element at pos counting from 1, NULL if none</span></div></div><!-- fragment --><p>The <code>soap_elt_get_next(elt)</code> function can be used in loops to iterate over child elements with the same namespace and tag, as if traversing an array. For example:</p>
<div class="fragment"><div class="line"><span class="comment">// iterate over &lt;menuitem&gt; child elements of element node &#39;dom&#39;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = <a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, NULL, <span class="stringliteral">&quot;menuitem&quot;</span>); it; it = <a class="code" href="dom_8cpp.html#aa2b4d8e388f66603b033a4c6e7a08303">soap_elt_get_next</a>(it))</div><div class="line">  ...</div></div><!-- fragment --><p>To obtain various properties of a <code>dom</code> element node:</p>
<div class="fragment"><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *elt = <a class="code" href="dom_8cpp.html#aafa5eae57d35b9f20315d809e54fd6af">soap_elt_parent</a>(dom); <span class="comment">// parent node, or NULL when root</span></div><div class="line"><span class="keywordtype">size_t</span>          n = <a class="code" href="dom_8cpp.html#a1fa6d6c8bcf437ec443cd997cb685171">soap_elt_depth</a>(dom);  <span class="comment">// depth from the root node (0 is root)</span></div><div class="line"><span class="keywordtype">size_t</span>          n = <a class="code" href="dom_8cpp.html#a339149ebbdb4327bd4544beb7615f8fe">soap_elt_len</a>(dom);    <span class="comment">// number of siblings that have the same tag name</span></div><div class="line"><span class="keywordtype">size_t</span>        pos = <a class="code" href="dom_8cpp.html#af2438ddc9aed595c81a4c161eb4e39b5">soap_elt_nth</a>(dom);    <span class="comment">// node is at pos with the same tag name as some siblings, or 0 if alone</span></div></div><!-- fragment --><p>The following invariants hold (assuming that <code>soap_elt_get(dom, ns, tag)</code> is not NULL and thus <code>dom</code> has a child element that matches namespace <code>ns</code> and <code>tag</code>):</p>
<div class="fragment"><div class="line"><a class="code" href="dom_8cpp.html#a53df62a627353cf06310a38b6c7046a0">soap_elt_match</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, tag), NULL, tag)             == <span class="keyword">true</span> (nonzero)</div><div class="line"><a class="code" href="dom_8cpp.html#aafa5eae57d35b9f20315d809e54fd6af">soap_elt_parent</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, tag))                       == dom</div><div class="line"><a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, NULL, tag))                      == tag</div><div class="line"></div><div class="line"><a class="code" href="dom_8cpp.html#a53df62a627353cf06310a38b6c7046a0">soap_elt_match</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, ns, tag), ns, tag)                 == <span class="keyword">true</span> (nonzero)</div><div class="line"><a class="code" href="dom_8cpp.html#aafa5eae57d35b9f20315d809e54fd6af">soap_elt_parent</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, ns, tag))                         == dom</div><div class="line"><a class="code" href="dom_8cpp.html#a77234d674c351892ad534f6c7fef6422">soap_elt_get_ns</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, ns, tag))                         == ns</div><div class="line"><a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(<a class="code" href="dom_8cpp.html#ab003b0c4e3c1b7883f40f2fcb87c5c9b">soap_elt</a>(dom, ns, tag))                        == tag</div><div class="line"></div><div class="line"><a class="code" href="dom_8cpp.html#afb4017b8f4bb5a2953167bc61ee937e9">soap_att_match</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, ns, tag), ns, tag)                 == <span class="keyword">true</span> (nonzero)</div><div class="line"><a class="code" href="dom_8cpp.html#a844c720c8dfa2b0bd9071aeb42ede82e">soap_att_get_ns</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, ns, tag))                         == ns</div><div class="line"><a class="code" href="dom_8cpp.html#af0d695aea7a6aadff918ec4150da3536">soap_att_get_tag</a>(<a class="code" href="dom_8cpp.html#a44d7c0b4ff8536b886558edfee90e131">soap_att</a>(dom, ns, tag))                        == tag</div><div class="line"></div><div class="line"><a class="code" href="dom_8cpp.html#ad9b8fc1a25f13e99aed9a39029c312f2">soap_elt_get_int</a>(<a class="code" href="dom_8cpp.html#aca27dd1369a7b124f5020357cb22163c">soap_elt_int</a>(dom, val))                        == val  <span class="comment">// also holds for bool, double, string</span></div><div class="line"><a class="code" href="dom_8cpp.html#a18360245b72c1b17fe20191a5c72cb71">soap_att_get_int</a>(<a class="code" href="dom_8cpp.html#adba6b7c98ea57dc2ef130eefee2273cd">soap_att_int</a>(dom, val))                        == val  <span class="comment">// also holds for bool, double, string</span></div><div class="line"></div><div class="line"><a class="code" href="dom_8cpp.html#aafa5eae57d35b9f20315d809e54fd6af">soap_elt_parent</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag))                     == dom</div><div class="line"><a class="code" href="dom_8cpp.html#a1fa6d6c8bcf437ec443cd997cb685171">soap_elt_depth</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag))                      == <a class="code" href="dom_8cpp.html#a1fa6d6c8bcf437ec443cd997cb685171">soap_elt_depth</a>(dom) + 1</div><div class="line"><a class="code" href="dom_8cpp.html#af2438ddc9aed595c81a4c161eb4e39b5">soap_elt_nth</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag))                        &lt;= <a class="code" href="dom_8cpp.html#a339149ebbdb4327bd4544beb7615f8fe">soap_elt_len</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag))</div><div class="line"><a class="code" href="dom_8cpp.html#af2438ddc9aed595c81a4c161eb4e39b5">soap_elt_nth</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag))                        == 0 if <a class="code" href="dom_8cpp.html#a339149ebbdb4327bd4544beb7615f8fe">soap_elt_len</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag)) == 1</div><div class="line"><a class="code" href="dom_8cpp.html#af2438ddc9aed595c81a4c161eb4e39b5">soap_elt_nth</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag))                        == 1 if <a class="code" href="dom_8cpp.html#a339149ebbdb4327bd4544beb7615f8fe">soap_elt_len</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag)) &gt;  1</div><div class="line"><a class="code" href="dom_8cpp.html#af2438ddc9aed595c81a4c161eb4e39b5">soap_elt_nth</a>(<a class="code" href="dom_8cpp.html#aa2b4d8e388f66603b033a4c6e7a08303">soap_elt_get_next</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag)))     == 2</div><div class="line"><a class="code" href="dom_8cpp.html#af2438ddc9aed595c81a4c161eb4e39b5">soap_elt_nth</a>(<a class="code" href="dom_8cpp.html#a76f66c5f1941c3330e10ef99a5604319">soap_elt_get_nth</a>(<a class="code" href="dom_8cpp.html#a0c451f3721567c575a751baef5bbc358">soap_elt_get</a>(dom, ns, tag), pos)) == pos</div></div><!-- fragment --><h3><a class="anchor" id="c-api4"></a>
Traversing a DOM node graph</h3>
<p>Given a DOM node graph <code>dom</code>, we can traverse its attribute list <code><a class="el" href="structsoap__dom__element.html#ac1fa51e03329993f94b94716d6608ec7" title="list of attribute nodes ">xsd__anyType::atts</a></code> and its child elements <code><a class="el" href="structsoap__dom__element.html#a966a36fcc95b748ef132869c3e829fbc" title="list of child element nodes ">xsd__anyType::elts</a></code> as follows:</p>
<div class="fragment"><div class="line"><span class="comment">// print attribute tags</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = dom-&gt;atts; it; it = it-&gt;<a class="code" href="structsoap__dom__attribute.html#a1fe86e9f5989c933658b46afc173d843">next</a>)</div><div class="line">  printf(<span class="stringliteral">&quot;@%s\n&quot;</span>, <a class="code" href="dom_8cpp.html#af0d695aea7a6aadff918ec4150da3536">soap_att_get_tag</a>(it));</div><div class="line"></div><div class="line"><span class="comment">// print child element tags</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = dom-&gt;<a class="code" href="structsoap__dom__element.html#a966a36fcc95b748ef132869c3e829fbc">elts</a>; it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a01ff512f31c46fe35b530d53d971d87e">next</a>)</div><div class="line">  printf(<span class="stringliteral">&quot;&lt;%s&gt;\n&quot;</span>, <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(it));</div></div><!-- fragment --><p>You can also traverse the entire node graph below a certain DOM element node <code>dom</code> in depth-first order starting with the current <code>dom</code> and stepping through all element nodes with <code>soap_dom_next_element(elt, end)</code> where <code>end</code> is a pointer to the ending element node (exclusive), usually the starting node of the graph traversal:</p>
<div class="fragment"><div class="line"><span class="comment">// print all element tags in depth-first order</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = dom; it; it = <a class="code" href="dom_8cpp.html#a604fac0276d0c49cb3fce0f684d320e5">soap_dom_next_element</a>(it, dom))</div><div class="line">  printf(<span class="stringliteral">&quot;&lt;%s&gt; at depth %zd\n&quot;</span>, <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(it), <a class="code" href="dom_8cpp.html#a1fa6d6c8bcf437ec443cd997cb685171">soap_elt_depth</a>(it));</div></div><!-- fragment --><h3><a class="anchor" id="c-api5"></a>
Searching a DOM node graph</h3>
<p>Given a DOM node graph, we can search its attribute list and its child elements by using a pattern with wildcards <code>*</code> to match namespace and/or tag names, similar to XPath <code>*</code> pattern matching:</p>
<div class="fragment"><div class="line"><span class="comment">// print attribute tags that match *:id (* matches any namespace, including default)</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = <a class="code" href="dom_8cpp.html#af33ab9d85bcbb4eb3569a172a1d418a3">soap_att_find</a>(dom, NULL, <span class="stringliteral">&quot;*:id&quot;</span>); it; it = <a class="code" href="dom_8cpp.html#a0a5ba1d59d8a3f81ea10c2baf683beb4">soap_att_find_next</a>(it, NULL, <span class="stringliteral">&quot;*:id&quot;</span>))</div><div class="line">  printf(<span class="stringliteral">&quot;@%s\n&quot;</span>, <a class="code" href="dom_8cpp.html#af0d695aea7a6aadff918ec4150da3536">soap_att_get_tag</a>(it));</div><div class="line"></div><div class="line"><span class="comment">// print element tags in namespace &quot;urn:one&quot; (assuming &quot;x&quot; is &quot;urn:one&quot; in the namespace table)</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = <a class="code" href="dom_8cpp.html#ab2225bea2effa89b190ca492849f534f">soap_elt_find</a>(dom, NULL, <span class="stringliteral">&quot;x:*&quot;</span>); it; it = <a class="code" href="dom_8cpp.html#ab1dc6368f16b4daed11fff149c70e93f">soap_elt_find_next</a>(it, NULL, <span class="stringliteral">&quot;x:*&quot;</span>))</div><div class="line">  printf(<span class="stringliteral">&quot;&lt;%s&gt;\n&quot;</span>, <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(it));</div></div><!-- fragment --><p>The above assumes that a namespace table is used that defines namespace <code>x</code>. Alternatively, you can specify namespace parameters that can be NULL or <code>"*"</code> to match any namespace URI (NULL can be used in place of a <code>"*"</code> pattern):</p>
<div class="fragment"><div class="line"><span class="comment">// print attribute tags that match *:id</span></div><div class="line"><a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = <a class="code" href="dom_8cpp.html#af33ab9d85bcbb4eb3569a172a1d418a3">soap_att_find</a>(dom, <span class="stringliteral">&quot;*&quot;</span>, <span class="stringliteral">&quot;id&quot;</span>); it; it = <a class="code" href="dom_8cpp.html#a0a5ba1d59d8a3f81ea10c2baf683beb4">soap_att_find_next</a>(it, <span class="stringliteral">&quot;*&quot;</span>, <span class="stringliteral">&quot;id&quot;</span>))</div><div class="line">  printf(<span class="stringliteral">&quot;@%s\n&quot;</span>, <a class="code" href="dom_8cpp.html#af0d695aea7a6aadff918ec4150da3536">soap_att_get_tag</a>(it));</div><div class="line"></div><div class="line"><span class="comment">// print element tags in namespace &quot;urn:one&quot;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = <a class="code" href="dom_8cpp.html#ab2225bea2effa89b190ca492849f534f">soap_elt_find</a>(dom, <span class="stringliteral">&quot;urn:one&quot;</span>, <span class="stringliteral">&quot;*&quot;</span>); it; it = <a class="code" href="dom_8cpp.html#ab1dc6368f16b4daed11fff149c70e93f">soap_elt_find_next</a>(it, <span class="stringliteral">&quot;urn:one&quot;</span>, <span class="stringliteral">&quot;*&quot;</span>))</div><div class="line">  printf(<span class="stringliteral">&quot;&lt;%s&gt;\n&quot;</span>, <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(it));</div></div><!-- fragment --><p>Patterns for namespaces and tags are not restricted to wildcards <code>*</code>. You can specify parts of a namespace URI or tag name and use one or more <code>*</code> to match the rest.</p>
<p>You can also search the entire node graph below a certain DOM element node in depth-first order starting with the current node:</p>
<div class="fragment"><div class="line"><span class="comment">// find all element nodes with attribute &quot;id&quot; deep in the node graph</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line"><span class="keywordflow">for</span> (it = <a class="code" href="dom_8cpp.html#ab8f6cdd9483e2d181284b470590232bf">soap_dom_find</a>(dom, NULL, <span class="stringliteral">&quot;@*:id&quot;</span>); it; it = <a class="code" href="dom_8cpp.html#a5d1dd9b5e89e41313dd57095a5c3404b">soap_dom_find_next</a>(it, dom, NULL, <span class="stringliteral">&quot;@*:id&quot;</span>)</div><div class="line">  printf(&quot;element &lt;%s&gt; has an @<span class="keywordtype">id</span>=%s\n&quot;, <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(it), <a class="code" href="dom_8cpp.html#a6810a34c76ca237fe7c40169ef1cffa2">soap_att_get_text</a>(<a class="code" href="dom_8cpp.html#af33ab9d85bcbb4eb3569a172a1d418a3">soap_att_find</a>(it, NULL, &quot;*:<span class="keywordtype">id</span>&quot;)));</div><div class="line"></div><div class="line"><span class="comment">// print all element tags in namespace &quot;urn:one&quot;</span></div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it;</div><div class="line">for (it = <a class="code" href="dom_8cpp.html#ab8f6cdd9483e2d181284b470590232bf">soap_dom_find</a>(dom, &quot;urn:one&quot;, &quot;*&quot;); it; it = <a class="code" href="dom_8cpp.html#a5d1dd9b5e89e41313dd57095a5c3404b">soap_dom_find_next</a>(it, dom, &quot;urn:one&quot;, &quot;*&quot;))</div><div class="line">  printf(&quot;&lt;%s&gt;\n&quot;, <a class="code" href="dom_8cpp.html#a1e0603d58c6e48dcadfdd4fe6f50112f">soap_elt_get_tag</a>(it));</div></div><!-- fragment --><h3><a class="anchor" id="c-api6"></a>
XML DOM parsing and writing from/to streams</h3>
<p>Reading and writing XML from/to files, streams and string buffers is done via the managing context by setting one of the following context members that control IO sources and sinks:</p>
<div class="fragment"><div class="line">ctx-&gt;recvfd = fd; <span class="comment">// an int file descriptor to read from (0 by default)</span></div><div class="line">ctx-&gt;sendfd = fd; <span class="comment">// an int file descriptor to write to (1 by default)</span></div><div class="line">ctx-&gt;is = cs;     <span class="comment">// C only: a const char* string to read from (soap-&gt;is will advance)</span></div><div class="line">ctx-&gt;os = &amp;cs;    <span class="comment">// C only: pointer to a const char*, will be set to point to the string output</span></div></div><!-- fragment --><p>To parse XML from a file descriptor <code>ctx-&gt;recvfd</code> into a DOM node graph you can use to soapcpp2 auto-generated <code>soap_read_xsd__anyType(ctx, dom)</code> function:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and parse XML from &#39;cin&#39; into &#39;dom&#39;</span></div><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, NULL);</div><div class="line">ctx-&gt;recvfd = stdin;</div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="dom_8cpp.html#ae6e7c0ccfcef59bd6b536d70a601e1e9">soap_read_xsd__anyType</a>(ctx, dom))</div><div class="line">  ... <span class="comment">// check for IO end parse errors</span></div><div class="line">...</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>To write a DOM node graph in XML to a file descriptor <code>ctx-&gt;sendfd</code> you can use the soapcpp2 auto-generated <code>soap_write_xsd__anyType(ctx, dom)</code> function:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and create a &#39;dom&#39;, write its XML to &#39;cout&#39;</span></div><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;store&quot;</span>);</div><div class="line">...</div><div class="line">ctx-&gt;sendfd = stdout;</div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="dom_8cpp.html#afd8f56d71b8afa28ea394033b440ca2f">soap_write_xsd__anyType</a>(ctx, dom))</div><div class="line">  ... <span class="comment">// check for IO errors</span></div><div class="line">...</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>You can also parse XML from a string into a DOM node graph by using the <code>ctx-&gt;is</code> input string and the soapcpp2 auto-generated <code>soap_read_xsd__anyType(ctx, dom)</code> function:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and parse XML from a string into &#39;dom&#39;</span></div><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *in = <span class="stringliteral">&quot;&lt;store&gt;&lt;book title=\&quot;Sayings of the Century\&quot;/&gt;&lt;/store&gt;&quot;</span>;</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, NULL);</div><div class="line">ctx-&gt;is = in;</div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="dom_8cpp.html#ae6e7c0ccfcef59bd6b536d70a601e1e9">soap_read_xsd__anyType</a>(ctx, dom))</div><div class="line">  ... <span class="comment">// check for IO end parse errors</span></div><div class="line">ctx-&gt;is = NULL;</div><div class="line">...</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>Likewise, you can write a DOM node graph in XML to a string by using the <code>ctx-&gt;os</code> output string pointer and the soapcpp2 auto-generated <code>soap_write_xsd__anyType(ctx, dom)</code> function:</p>
<div class="fragment"><div class="line"><span class="comment">// create new context and create a &#39;dom&#39;, write its XML to a string</span></div><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *out = NULL;</div><div class="line"><a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *dom = <a class="code" href="dom_8cpp.html#a509d2cd902256e7876118db7933461e1">soap_elt_new</a>(ctx, NULL, <span class="stringliteral">&quot;store&quot;</span>);</div><div class="line">...</div><div class="line">ctx-&gt;os = &amp;out;                    <span class="comment">// string to set to point to the output</span></div><div class="line"><a class="code" href="dom_8cpp.html#afd8f56d71b8afa28ea394033b440ca2f">soap_write_xsd__anyType</a>(ctx, dom); <span class="comment">// convert DOM to XML string in UTF-8</span></div><div class="line">ctx-&gt;os = NULL;</div><div class="line">printf(<span class="stringliteral">&quot;%s\n&quot;</span>, out);</div><div class="line">...</div><div class="line">soap_end(ctx);</div><div class="line">soap_free(ctx);</div></div><!-- fragment --><p>The <code>soap_read_xsd__anyType(ctx, dom)</code> and <code>soap_write_xsd__anyType(ctx, dom)</code> functions return <code>SOAP_OK</code> (zero) or an error code in <code>ctx-&gt;error</code>.</p>
<p>It is also possible to send and receive XML over HTTP as REST operations as was illustrated in the introduction. To make REST HTTP POST, GET, PUT, and DELETE calls, use <code>soap_dom_call</code>. This function optionally takes a DOM to send or NULL to send nothing and optionally a DOM to receive or NULL to receive nothing (e.g. with HTTP PUT). The function returns <code>SOAP_OK</code> (zero) for success or an error code:</p>
<ul>
<li><code>int soap_dom_call(struct soap *ctx, const char *URL, const char *action, const xsd__anyType *in, xsd__anyType *out)</code> Make a POST, GET, PUT, DELETE call. Connect to endpoint <code>URL</code> with HTTP SOAPAction <code>action</code> (or NULL) and send request <code>in</code> to server and receive response <code>out</code>. Returns <code>SOAP_OK</code> (zero) or an error code, including HTTP error codes. POST method: pass both <code>in</code> and <code>out</code>. GET method: pass a NULL to <code>in</code>. PUT method: pass a NULL to <code>out</code>. DELETE method: pass both NULL to <code>in</code> and <code>out</code>.</li>
</ul>
<p>If the server response does not include an HTTP body with XML, then an HTTP error code is returned such as 200. If the server responds with HTTP codes 200, 400 and 500 with an HTTP body with XML, <code>SOAP_OK</code> is returned. The 400 and 500 HTTP status codes may be used to return SOAP/XML Fault messages and are therefore not returned as error codes.</p>
<h1><a class="anchor" id="opt"></a>
XML DOM parsing and display options                                       </h1>
<p>The soap context flags that control XML parsing and visual display are set when the context is created or with the <code>soap_set_mode</code> and <code>soap_clr_mode</code> functions:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_DOM_TREE);</div><div class="line"></div><div class="line">soap_set_mode(ctx, SOAP_XML_INDENT);  <span class="comment">// use indent</span></div><div class="line"></div><div class="line">soap_clr_mode(ctx, SOAP_XML_INDENT);  <span class="comment">// no indent</span></div></div><!-- fragment --><p>Options to control XML parsing, object serialization, and XML rendition are:</p>
<ul>
<li>(no flag): only elements with an <code>id</code> attribute are deserialized as C/C++ data types when a deserializer is available. This is to ensure that the SOAP encoding protocol deos not break when id-ref attibutes are used for multireferenced objects.</li>
<li><code>SOAP_DOM_TREE</code>: prevents deserialization of C/C++ data structures into the DOM even when an <code>id</code> attribute is present.</li>
<li><code>SOAP_DOM_NODE</code>: deserialize C/C++ data structures into the DOM. A deserializer is selected based on matching the element tag name or the xsi:type attribute value with the C/C++ type name.</li>
<li><code>SOAP_DOM_ASIS</code>: render XML "as is", i.e. do not insert xmlns bindings for URIs internally stored with nodes. Assumes that the DOM is self-contained with respect to namespaces.</li>
<li><code>SOAP_XML_INDENT</code>: render XML with indent.</li>
<li><code>SOAP_XML_CANONICAL</code>: render XML in canonical (exc-c14n) form.</li>
<li><code>SOAP_C_UTFSTRING</code>: the XML DOM always uses UTF-8, but embedded serializable objects only use UTF-8 when this flag is also set.</li>
</ul>
<h1><a class="anchor" id="dom"></a>
Using DOM together with serializeble types in a gSOAP header file         </h1>
<p>To use DOM nodes with types declared in a gSOAP header file, import <code><a class="el" href="dom_8h.html">dom.h</a></code> into your header file for processing with soapcpp2:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;<a class="code" href="dom_8h.html">dom.h</a>&quot;</span></div></div><!-- fragment --><p>The import is automatically added by wsdl2h with option <code>-d</code>. The wsdl2h tool binds xsd:anyType, xsd:any, xsd:anyAttribute and xsd:mixed XML content to DOM nodes instead of using XML literal strings.</p>
<p>The <code>#import "dom.h"</code> enables us use the DOM <code>xsd__anyType</code> element node and <code>xsd__anyAttribute</code> attribute node in a gSOAP header file type declarations, such as:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;<a class="code" href="dom_8h.html">dom.h</a>&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">class </span>ns__record</div><div class="line">{</div><div class="line"> <span class="keyword">public</span>:</div><div class="line">  @<a class="code" href="structsoap__dom__attribute.html">xsd__anyAttribute</a>  atts;  <span class="comment">// list of DOM attributes</span></div><div class="line">  ...</div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>        __any; <span class="comment">// xsd:any, consumes all other XML</span></div><div class="line">};</div></div><!-- fragment --><p>where <code>__any</code> contains XML stored in a DOM node set and <code>atts</code> is a list of all visibly rendered attributes. The name <code>atts</code> is arbitrary and any name will suffice.</p>
<p>We should place the <code>xsd__anyType</code> members at the end of the struct or class. This ensures that the DOM members are populated last as a "catch all". A member name starting with double underscore is a wildcard member name and matches any XML tag. These members are placed at the end of a struct or class automatically by soapcpp2.</p>
<p>The soapcpp2 tool generates code that "serializes" the DOM nodes as part of the serialization of the C/C++ types in which they are used.</p>
<dl class="section see"><dt>See also</dt><dd>Documentation of <a href="http://www.genivia.com/doc/databinding/html/index.html#toxsd10-5">XML Data Bindings: DOM anyType and anyAttribute</a>.</dd></dl>
<h1><a class="anchor" id="example"></a>
Example                                                               </h1>
<p>This example demonstrates the domcpp tool to generate code for a SOAP request message to send to a calculator service and to generate code to obtain the floating point value from the SOAP response returned. The generated code is copied and modified to create a DOM-based SOAP client application in C++ <code><a class="el" href="dom2calc_8cpp.html">dom2calc.cpp</a></code>.</p>
<p>We use a very simple calculator service to demonstrate the C++ DOM API to populate a DOM node graph and to query a DOM node graph. The codes to accomplish both of these tasks can be generated with domcpp and modified as needed for our purposes.</p>
<p>The SOAP calculator service and client on which this example is based are located in <code>gsoap/samples/calc</code> (for C) and <code>gsoap/samples/calc++</code> (for C++) in the gSOAP package.</p>
<p>We use the SOAP calculator sample SOAP message <code>calc.add.req.xml</code> generated by soapcpp2 in <code>gsoap/samples/calc++</code>. This XML message contains a SOAP request to add two floating point values:</p>
<div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;&lt;SOAP-ENV:Envelope</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;  xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;  xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  xmlns:ns=&quot;urn:calc&quot;&gt;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160; &lt;SOAP-ENV:Body SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;&gt;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;  &lt;ns:add&gt;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;   &lt;a&gt;0.0&lt;/a&gt;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;   &lt;b&gt;0.0&lt;/b&gt;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;  &lt;/ns:add&gt;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160; &lt;/SOAP-ENV:Body&gt;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;&lt;/SOAP-ENV:Envelope&gt;</div></div><!-- fragment --> </div><p>To generate code that populates this SOAP request message as a DOM node graph, we invoke: </p><pre class="fragment">domcpp -M -n -rrequest calc.add.req.xml
</pre><p>We copied the generated code into <code><a class="el" href="dom2calc_8cpp.html">dom2calc.cpp</a></code> as shown further below.</p>
<p>A sample SOAP response message <code>calc.add.res.xml</code> from the calculator service is:</p>
<div class="alt"> <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;&lt;SOAP-ENV:Envelope</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;  xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;  xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  xmlns:ns=&quot;urn:calc&quot;&gt;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160; &lt;SOAP-ENV:Body SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;&gt;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;  &lt;ns:addResponse&gt;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;   &lt;result&gt;0.0&lt;/result&gt;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;  &lt;/ns:addResponse&gt;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160; &lt;/SOAP-ENV:Body&gt;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;&lt;/SOAP-ENV:Envelope&gt;</div></div><!-- fragment --> </div><p>We want to generate code that inspects the SOAP response message to extract the value of <code>&lt;result&gt;</code>. For this purpose we can use the XPath query <code>/SOAP-ENV:Envelope/SOAP-ENV:Body/ns:addResponse/result</code> and use this XPath with domcpp option <code>-p</code> and option <code>-x</code> to generate code that prints the <code>&lt;result&gt;</code> value: </p><pre class="fragment">domcpp -p'/SOAP-ENV:Envelope/SOAP-ENV:Body/ns:addResponse/result' \
  -rresponse -x'std::cout &lt;&lt; "Result = " &lt;&lt; v &lt;&lt; std::endl;'
</pre><p>We copied the generated code into <code><a class="el" href="dom2calc_8cpp.html">dom2calc.cpp</a></code> as shown below:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;soapH.h&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> <a class="code" href="dom2calc_8cpp.html#a29a976128bd452a68a0012e4b63557a6">server</a>[] = <span class="stringliteral">&quot;http://websrv.cs.fsu.edu/~engelen/calcserver.cgi&quot;</span>;</div><div class="line"></div><div class="line"><span class="comment">// copied from:</span></div><div class="line"><span class="comment">// domcpp -M -n -rrequest calc.add.req.xml</span></div><div class="line"><span class="keyword">struct </span>Namespace namespaces[] = {</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENV&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-envelope&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;SOAP-ENC&quot;</span>, <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/soap-encoding&quot;</span>,      NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsi&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>, <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema-instance&quot;</span>, NULL},</div><div class="line">  {<span class="stringliteral">&quot;xsd&quot;</span>,      <span class="stringliteral">&quot;http://www.w3.org/2001/XMLSchema&quot;</span>,          <span class="stringliteral">&quot;http://www.w3.org/*/XMLSchema&quot;</span>,          NULL},</div><div class="line">  {<span class="stringliteral">&quot;ns&quot;</span>, <span class="stringliteral">&quot;urn:calc&quot;</span>, NULL, NULL },</div><div class="line">  {NULL, NULL, NULL, NULL}</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> <a class="code" href="dom2calc_8cpp.html#a3c04138a5bfe5d72780bb7e82a18e627">main</a>(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)</div><div class="line">{</div><div class="line">  <span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_DOM_TREE | SOAP_XML_INDENT);</div><div class="line"></div><div class="line">  <span class="keywordflow">if</span> (argc &lt;= 3)</div><div class="line">  {</div><div class="line">    std::cerr &lt;&lt; <span class="stringliteral">&quot;Usage: dom2calc [add|sub|mul|div|pow] &lt;num&gt; &lt;num&gt;&quot;</span> &lt;&lt; std::endl;</div><div class="line">    exit(1);</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// create command tag ns:add, ns:sub, ns:mul, ns:div, or ns:pow</span></div><div class="line">  std::string command = std::string(<span class="stringliteral">&quot;ns:&quot;</span>).append(argv[1]);</div><div class="line"></div><div class="line">  <span class="comment">// copied and modified from:</span></div><div class="line">  <span class="comment">// domcpp -M -n -rrequest calc.add.req.xml</span></div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> request(ctx, <span class="stringliteral">&quot;SOAP-ENV:Envelope&quot;</span>);</div><div class="line">  request[<span class="stringliteral">&quot;SOAP-ENV:Body&quot;</span>].att(<span class="stringliteral">&quot;SOAP-ENV:encodingStyle&quot;</span>) = <span class="stringliteral">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span>;</div><div class="line">  request[<span class="stringliteral">&quot;SOAP-ENV:Body&quot;</span>][command.c_str()][<span class="stringliteral">&quot;a&quot;</span>] = strtod(argv[2], NULL);</div><div class="line">  request[<span class="stringliteral">&quot;SOAP-ENV:Body&quot;</span>][command.c_str()][<span class="stringliteral">&quot;b&quot;</span>] = strtod(argv[3], NULL);</div><div class="line"></div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;** Request message: &quot;</span> &lt;&lt; std::endl &lt;&lt; request &lt;&lt; std::endl &lt;&lt; std::endl;</div><div class="line"></div><div class="line">  <span class="comment">// create response</span></div><div class="line">  <a class="code" href="structsoap__dom__element.html">xsd__anyType</a> response(ctx);</div><div class="line"></div><div class="line">  <span class="comment">// invoke server: make POST XML request and receive XML response</span></div><div class="line">  <span class="keywordflow">if</span> (<a class="code" href="dom_8cpp.html#ac69b3f6b7f7ee9f695050632b9c26fdc">soap_dom_call</a>(ctx, server, <span class="stringliteral">&quot;&quot;</span>, request, response))</div><div class="line">  {</div><div class="line">    soap_stream_fault(ctx, std::cerr);</div><div class="line">  }</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">  {</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;** Response message:&quot;</span> &lt;&lt; std::endl &lt;&lt; response &lt;&lt; std::endl &lt;&lt; std::endl;</div><div class="line"></div><div class="line">    <span class="comment">// copied from:</span></div><div class="line">    <span class="comment">// domcpp -p&#39;/SOAP-ENV:Envelope/SOAP-ENV:Body/ns:addResponse/result&#39; -rresponse -x&#39;std::cout &lt;&lt; &quot;Result = &quot; &lt;&lt; v &lt;&lt; std::endl;&#39;</span></div><div class="line">    <span class="keywordflow">if</span> (response.match(<span class="stringliteral">&quot;SOAP-ENV:Envelope&quot;</span>))</div><div class="line">    {</div><div class="line">      <span class="keywordtype">size_t</span> pos = 1;</div><div class="line">      <span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it = response.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;SOAP-ENV:Body&quot;</span>); it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>(), ++pos)</div><div class="line">      {</div><div class="line">        <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; v = *it;</div><div class="line">        <span class="keywordtype">size_t</span> pos = 1;</div><div class="line">        <span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it = v.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;ns:addResponse&quot;</span>); it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>(), ++pos)</div><div class="line">        {</div><div class="line">          <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; v = *it;</div><div class="line">          <span class="keywordtype">size_t</span> pos = 1;</div><div class="line">          <span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html">xsd__anyType</a> *it = v.<a class="code" href="structsoap__dom__element.html#aaf7c6bf74f938aeaf423760015a4f7fe">elt_get</a>(<span class="stringliteral">&quot;result&quot;</span>); it; it = it-&gt;<a class="code" href="structsoap__dom__element.html#a5653d5366588e49e90d5c667258da7c0">get_next</a>(), ++pos)</div><div class="line">          {</div><div class="line">            <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>&amp; v = *it;</div><div class="line">            std::cout &lt;&lt; <span class="stringliteral">&quot;Result = &quot;</span> &lt;&lt; v.<a class="code" href="structsoap__dom__element.html#a3c35464cc97997297e645d53e50e3100">get_double</a>() &lt;&lt; std::endl;</div><div class="line">          }</div><div class="line">        }</div><div class="line">      }</div><div class="line">    }</div><div class="line">  }</div><div class="line"></div><div class="line">  soap_destroy(ctx); <span class="comment">// delete objects</span></div><div class="line">  soap_end(ctx);     <span class="comment">// delete temp data</span></div><div class="line">  soap_free(ctx);    <span class="comment">// free context</span></div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>To compile <code><a class="el" href="dom2calc_8cpp.html">dom2calc.cpp</a></code> we first generate <code>soapC.cpp</code>, <code>soapStub.h</code> and <code>soapH.h</code> from the gSOAP header file <code><a class="el" href="dom_8h.html">dom.h</a></code>: </p><pre class="fragment">soapcpp2 dom.h
c++ -o dom2calc dom2calc.cpp soapC.cpp dom.cpp stdsoap2.cpp
</pre><p>Running the DOM-based calculator client gives: </p><pre class="fragment">./dom2calc add 3 4

** Request message: 
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&gt;
        &lt;SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;
                &lt;ns:add xmlns:ns="urn:calc"&gt;
                        &lt;a&gt;3&lt;/a&gt;
                        &lt;b&gt;4&lt;/b&gt;
                &lt;/ns:add&gt;
        &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;

** Response message:
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:calc"&gt;
        &lt;SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;
                &lt;ns:addResponse&gt;
                        &lt;result&gt;7&lt;/result&gt;
                &lt;/ns:addResponse&gt;
        &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;

Result = 7
</pre><p>Another way to extract the floating point value from the SOAP response is to use the <code><a class="el" href="structsoap__dom__element.html#ac95906c740883f1184c053c865c210b0" title="Return iterator to search deep depth-first over node graph starting from this node, same as find(NULL, patt, type) ">xsd__anyType::find()</a></code> method to search (and iterate) over <code>&lt;result&gt;</code> elements:</p>
<div class="fragment"><div class="line"><span class="keywordflow">for</span> (<a class="code" href="structsoap__dom__element.html#acd8085cf400dadfee161faa0867258a9">xsd__anyType::iterator</a> it = response.find(<span class="stringliteral">&quot;result&quot;</span>); it != response.end(); ++it)</div><div class="line">  std::cout &lt;&lt; std::endl &lt;&lt; <span class="stringliteral">&quot;Result = &quot;</span> &lt;&lt; it-&gt;get_double() &lt;&lt; std::endl;</div></div><!-- fragment --><p>where the <code><a class="el" href="structsoap__dom__element.html#a3c35464cc97997297e645d53e50e3100" title="Return double float value of decimal text of this xsd__anyType DOM element node. ">xsd__anyType::get_double()</a></code> method is used to cast the XML value to a <code>double</code>.</p>
<h1><a class="anchor" id="misc"></a>
Miscellaneous                                                            </h1>
<h2><a class="anchor" id="fp"></a>
Floating point format                                                      </h2>
<p>The floating point format used to output values in XML-RPC and JSON is by default ".17lG' to ensure accuracy up to the last digit. The format can be set as follows:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT);</div><div class="line">ctx-&gt;double_format = <span class="stringliteral">&quot;%lG&quot;</span>;</div></div><!-- fragment --><h1><a class="anchor" id="copyright"></a>
Copyright                                                           </h1>
<p>Copyright (c) 2017, Robert van Engelen, Genivia Inc. All rights reserved. </p>
</div></div><!-- contents -->
<hr class="footer">
<address class="footer">
Copyright (C) 2021, Robert van Engelen, Genivia Inc., All Rights Reserved.
</address>
<address class="footer"><small>
Converted on Wed Aug 11 2021 09:52:34 by <a target="_blank" href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.11</small></address>
<br>
<div style="height: 246px; background: #DBDBDB;">
</body>
</html>
